AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
Spell Class Reference

#include "Spell.h"

Classes

struct  GOTargetInfo
 
struct  HitTriggerSpell
 
struct  ItemTargetInfo
 

Public Types

typedef std::set< Aura * > UsedSpellMods
 

Public Member Functions

 Spell (Unit *caster, SpellInfo const *info, TriggerCastFlags triggerFlags, ObjectGuid originalCasterGUID=ObjectGuid::Empty, bool skipCheck=false)
 
 ~Spell ()
 
void EffectNULL (SpellEffIndex effIndex)
 
void EffectUnused (SpellEffIndex effIndex)
 
void EffectDistract (SpellEffIndex effIndex)
 
void EffectPull (SpellEffIndex effIndex)
 
void EffectSchoolDMG (SpellEffIndex effIndex)
 
void EffectEnvironmentalDMG (SpellEffIndex effIndex)
 
void EffectInstaKill (SpellEffIndex effIndex)
 
void EffectDummy (SpellEffIndex effIndex)
 
void EffectTeleportUnits (SpellEffIndex effIndex)
 
void EffectApplyAura (SpellEffIndex effIndex)
 
void EffectSendEvent (SpellEffIndex effIndex)
 
void EffectPowerBurn (SpellEffIndex effIndex)
 
void EffectPowerDrain (SpellEffIndex effIndex)
 
void EffectHeal (SpellEffIndex effIndex)
 
void EffectBind (SpellEffIndex effIndex)
 
void EffectHealthLeech (SpellEffIndex effIndex)
 
void EffectQuestComplete (SpellEffIndex effIndex)
 
void EffectCreateItem (SpellEffIndex effIndex)
 
void EffectCreateItem2 (SpellEffIndex effIndex)
 
void EffectCreateRandomItem (SpellEffIndex effIndex)
 
void EffectPersistentAA (SpellEffIndex effIndex)
 
void EffectEnergize (SpellEffIndex effIndex)
 
void EffectOpenLock (SpellEffIndex effIndex)
 
void EffectSummonChangeItem (SpellEffIndex effIndex)
 
void EffectProficiency (SpellEffIndex effIndex)
 
void EffectApplyAreaAura (SpellEffIndex effIndex)
 
void EffectSummonType (SpellEffIndex effIndex)
 
void EffectLearnSpell (SpellEffIndex effIndex)
 
void EffectDispel (SpellEffIndex effIndex)
 
void EffectDualWield (SpellEffIndex effIndex)
 
void EffectPickPocket (SpellEffIndex effIndex)
 
void EffectAddFarsight (SpellEffIndex effIndex)
 
void EffectUntrainTalents (SpellEffIndex effIndex)
 
void EffectHealMechanical (SpellEffIndex effIndex)
 
void EffectJump (SpellEffIndex effIndex)
 
void EffectJumpDest (SpellEffIndex effIndex)
 
void EffectLeapBack (SpellEffIndex effIndex)
 
void EffectQuestClear (SpellEffIndex effIndex)
 
void EffectTeleUnitsFaceCaster (SpellEffIndex effIndex)
 
void EffectLearnSkill (SpellEffIndex effIndex)
 
void EffectAddHonor (SpellEffIndex effIndex)
 
void EffectTradeSkill (SpellEffIndex effIndex)
 
void EffectEnchantItemPerm (SpellEffIndex effIndex)
 
void EffectEnchantItemTmp (SpellEffIndex effIndex)
 
void EffectTameCreature (SpellEffIndex effIndex)
 
void EffectSummonPet (SpellEffIndex effIndex)
 
void EffectLearnPetSpell (SpellEffIndex effIndex)
 
void EffectWeaponDmg (SpellEffIndex effIndex)
 
void EffectForceCast (SpellEffIndex effIndex)
 
void EffectTriggerSpell (SpellEffIndex effIndex)
 
void EffectTriggerMissileSpell (SpellEffIndex effIndex)
 
void EffectThreat (SpellEffIndex effIndex)
 
void EffectHealMaxHealth (SpellEffIndex effIndex)
 
void EffectInterruptCast (SpellEffIndex effIndex)
 
void EffectSummonObjectWild (SpellEffIndex effIndex)
 
void EffectScriptEffect (SpellEffIndex effIndex)
 
void EffectSanctuary (SpellEffIndex effIndex)
 
void EffectAddComboPoints (SpellEffIndex effIndex)
 
void EffectDuel (SpellEffIndex effIndex)
 
void EffectStuck (SpellEffIndex effIndex)
 
void EffectSummonPlayer (SpellEffIndex effIndex)
 
void EffectActivateObject (SpellEffIndex effIndex)
 
void EffectApplyGlyph (SpellEffIndex effIndex)
 
void EffectEnchantHeldItem (SpellEffIndex effIndex)
 
void EffectSummonObject (SpellEffIndex effIndex)
 
void EffectResurrect (SpellEffIndex effIndex)
 
void EffectParry (SpellEffIndex effIndex)
 
void EffectBlock (SpellEffIndex effIndex)
 
void EffectLeap (SpellEffIndex effIndex)
 
void EffectTransmitted (SpellEffIndex effIndex)
 
void EffectDisEnchant (SpellEffIndex effIndex)
 
void EffectInebriate (SpellEffIndex effIndex)
 
void EffectFeedPet (SpellEffIndex effIndex)
 
void EffectDismissPet (SpellEffIndex effIndex)
 
void EffectReputation (SpellEffIndex effIndex)
 
void EffectForceDeselect (SpellEffIndex effIndex)
 
void EffectSelfResurrect (SpellEffIndex effIndex)
 
void EffectSkinning (SpellEffIndex effIndex)
 
void EffectCharge (SpellEffIndex effIndex)
 
void EffectChargeDest (SpellEffIndex effIndex)
 
void EffectProspecting (SpellEffIndex effIndex)
 
void EffectMilling (SpellEffIndex effIndex)
 
void EffectRenamePet (SpellEffIndex effIndex)
 
void EffectSendTaxi (SpellEffIndex effIndex)
 
void EffectSummonCritter (SpellEffIndex effIndex)
 
void EffectKnockBack (SpellEffIndex effIndex)
 
void EffectPullTowards (SpellEffIndex effIndex)
 
void EffectDispelMechanic (SpellEffIndex effIndex)
 
void EffectResurrectPet (SpellEffIndex effIndex)
 
void EffectDestroyAllTotems (SpellEffIndex effIndex)
 
void EffectDurabilityDamage (SpellEffIndex effIndex)
 
void EffectSkill (SpellEffIndex effIndex)
 
void EffectTaunt (SpellEffIndex effIndex)
 
void EffectDurabilityDamagePCT (SpellEffIndex effIndex)
 
void EffectModifyThreatPercent (SpellEffIndex effIndex)
 
void EffectResurrectNew (SpellEffIndex effIndex)
 
void EffectAddExtraAttacks (SpellEffIndex effIndex)
 
void EffectSpiritHeal (SpellEffIndex effIndex)
 
void EffectSkinPlayerCorpse (SpellEffIndex effIndex)
 
void EffectStealBeneficialBuff (SpellEffIndex effIndex)
 
void EffectUnlearnSpecialization (SpellEffIndex effIndex)
 
void EffectHealPct (SpellEffIndex effIndex)
 
void EffectEnergizePct (SpellEffIndex effIndex)
 
void EffectTriggerRitualOfSummoning (SpellEffIndex effIndex)
 
void EffectSummonRaFFriend (SpellEffIndex effIndex)
 
void EffectKillCreditPersonal (SpellEffIndex effIndex)
 
void EffectKillCredit (SpellEffIndex effIndex)
 
void EffectQuestFail (SpellEffIndex effIndex)
 
void EffectQuestStart (SpellEffIndex effIndex)
 
void EffectRedirectThreat (SpellEffIndex effIndex)
 
void EffectGameObjectDamage (SpellEffIndex effIndex)
 
void EffectGameObjectRepair (SpellEffIndex effIndex)
 
void EffectGameObjectSetDestructionState (SpellEffIndex effIndex)
 
void EffectActivateRune (SpellEffIndex effIndex)
 
void EffectCreateTamedPet (SpellEffIndex effIndex)
 
void EffectDiscoverTaxi (SpellEffIndex effIndex)
 
void EffectTitanGrip (SpellEffIndex effIndex)
 
void EffectEnchantItemPrismatic (SpellEffIndex effIndex)
 
void EffectPlayMusic (SpellEffIndex effIndex)
 
void EffectSpecCount (SpellEffIndex effIndex)
 
void EffectActivateSpec (SpellEffIndex effIndex)
 
void EffectPlaySound (SpellEffIndex effIndex)
 
void EffectRemoveAura (SpellEffIndex effIndex)
 
void EffectCastButtons (SpellEffIndex effIndex)
 
void EffectRechargeManaGem (SpellEffIndex effIndex)
 
void InitExplicitTargets (SpellCastTargets const &targets)
 
void SelectExplicitTargets ()
 
void SelectSpellTargets ()
 
void SelectEffectImplicitTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 &processedEffectMask)
 
void SelectImplicitChannelTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitNearbyTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitConeTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitAreaTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitCasterDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitTargetDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitDestDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitCasterObjectTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitTargetObjectTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitChainTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, WorldObject *target, uint32 effMask)
 
void SelectImplicitTrajTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectEffectTypeImplicitTargets (uint8 effIndex)
 
uint32 GetSearcherTypeMask (SpellTargetObjectTypes objType, std::shared_ptr< ConditionList > condList)
 
template<class SEARCHER >
void SearchTargets (SEARCHER &searcher, uint32 containerMask, Unit *referer, Position const *pos, float radius)
 
WorldObjectSearchNearbyTarget (float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, std::shared_ptr< ConditionList > condList=nullptr)
 
void SearchAreaTargets (std::list< WorldObject * > &targets, float range, Position const *position, Unit *referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, std::shared_ptr< ConditionList > condList)
 
void SearchChainTargets (std::list< WorldObject * > &targets, uint32 chainTargets, WorldObject *target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, SpellTargetSelectionCategories selectCategory, std::shared_ptr< ConditionList > condList, bool isChainHeal)
 
SpellCastResult prepare (SpellCastTargets const *targets, AuraEffect const *triggeredByAura=nullptr)
 
void cancel (bool bySelf=false)
 
void update (uint32 difftime)
 
void cast (bool skipCheck=false)
 
void _cast (bool skipCheck)
 
void finish (bool ok=true)
 
void TakePower ()
 
void TakeAmmo ()
 
void TakeRunePower (bool didHit)
 
void TakeReagents ()
 
void TakeCastItem ()
 
SpellCastResult CheckCast (bool strict)
 
SpellCastResult CheckPetCast (Unit *target)
 
void handle_immediate ()
 
uint64 handle_delayed (uint64 t_offset)
 
void _handle_immediate_phase ()
 
void _handle_finish_phase ()
 
void OnSpellLaunch ()
 
SpellCastResult CheckItems ()
 
SpellCastResult CheckSpellFocus ()
 
SpellCastResult CheckRange (bool strict)
 
SpellCastResult CheckPower ()
 
SpellCastResult CheckRuneCost (uint32 RuneCostID)
 
SpellCastResult CheckCasterAuras (bool preventionOnly) const
 
int32 CalculateSpellDamage (uint8 i, Unit const *target) const
 
bool HaveTargetsForEffect (uint8 effect) const
 
void Delayed ()
 
void DelayedChannel ()
 
uint32 getState () const
 
void setState (uint32 state)
 
void DoCreateItem (uint8 effIndex, uint32 itemId)
 
void WriteSpellGoTargets (WorldPacket *data)
 Writes miss and hit targets for a SMSG_SPELL_GO packet.
 
void WriteAmmoToPacket (WorldPacket *data)
 
bool CheckEffectTarget (Unit const *target, uint32 eff) const
 
bool CanAutoCast (Unit *target)
 
void CheckSrc ()
 
void CheckDst ()
 
void SendCastResult (SpellCastResult result)
 
void SendPetCastResult (SpellCastResult result)
 
void SendSpellStart ()
 
void SendSpellGo ()
 
void SendSpellCooldown ()
 
void SendLogExecute ()
 
void ExecuteLogEffectTakeTargetPower (uint8 effIndex, Unit *target, uint32 PowerType, uint32 powerTaken, float gainMultiplier)
 
void ExecuteLogEffectExtraAttacks (uint8 effIndex, Unit *victim, uint32 attCount)
 
void ExecuteLogEffectInterruptCast (uint8 effIndex, Unit *victim, uint32 spellId)
 
void ExecuteLogEffectDurabilityDamage (uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
 
void ExecuteLogEffectOpenLock (uint8 effIndex, Object *obj)
 
void ExecuteLogEffectCreateItem (uint8 effIndex, uint32 entry)
 
void ExecuteLogEffectDestroyItem (uint8 effIndex, uint32 entry)
 
void ExecuteLogEffectSummonObject (uint8 effIndex, WorldObject *obj)
 
void ExecuteLogEffectUnsummonObject (uint8 effIndex, WorldObject *obj)
 
void ExecuteLogEffectResurrect (uint8 effIndex, Unit *target)
 
void SendInterrupted (uint8 result)
 
void SendChannelUpdate (uint32 time)
 
void SendChannelStart (uint32 duration)
 
void SendResurrectRequest (Player *target)
 
void HandleEffects (Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
 
void HandleThreatSpells ()
 
void AddComboPointGain (Unit *target, int8 amount)
 
int32 GetCastTime () const
 
bool IsAutoRepeat () const
 
void SetAutoRepeat (bool rep)
 
void ReSetTimer ()
 
int32 GetCastTimeRemaining ()
 
bool IsNextMeleeSwingSpell () const
 
bool IsTriggered () const
 
bool HasTriggeredCastFlag (TriggerCastFlags flag) const
 
bool IsChannelActive () const
 
bool IsAutoActionResetSpell () const
 
bool IsIgnoringCooldowns () const
 
bool IsDeletable () const
 
void SetReferencedFromCurrent (bool yes)
 
bool IsInterruptable () const
 
void SetExecutedCurrently (bool yes)
 
uint64 GetDelayStart () const
 
void SetDelayStart (uint64 m_time)
 
uint64 GetDelayMoment () const
 
uint64 GetDelayTrajectory () const
 
uint64 CalculateDelayMomentForDst () const
 
void RecalculateDelayMomentForDst ()
 
bool IsNeedSendToClient (bool go) const
 
CurrentSpellTypes GetCurrentContainer () const
 
UnitGetCaster () const
 
UnitGetOriginalCaster () const
 
SpellInfo const * GetSpellInfo () const
 
int32 GetPowerCost () const
 
bool UpdatePointers ()
 
void CleanupTargetList ()
 
void SetSpellValue (SpellValueMod mod, int32 value)
 
SpellValue const * GetSpellValue ()
 
void LoadScripts ()
 
std::list< TargetInfo > * GetUniqueTargetInfo ()
 
uint32 GetTriggeredByAuraTickNumber () const
 
TriggerCastFlags GetTriggeredCastFlags () const
 
SpellSchoolMask GetSpellSchoolMask () const
 

Static Public Member Functions

static void WriteCastResultInfo (WorldPacket &data, Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError)
 
static void SendCastResult (Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
 

Public Attributes

SpellInfo const *const m_spellInfo
 
Itemm_CastItem
 
Itemm_weaponItem
 
ObjectGuid m_castItemGUID
 
uint8 m_cast_count
 
uint32 m_glyphIndex
 
uint32 m_preCastSpell
 
SpellCastTargets m_targets
 
SpellCustomErrors m_customError
 
Unitm_comboTarget
 
int8 m_comboPointGain
 
UsedSpellMods m_appliedMods
 

Protected Types

typedef std::list< HitTriggerSpellHitTriggerSpellList
 

Protected Member Functions

bool HasGlobalCooldown () const
 
void TriggerGlobalCooldown ()
 
void CancelGlobalCooldown ()
 
void SendLoot (ObjectGuid guid, LootType loottype)
 
std::string GetDebugInfo () const
 
bool isDelayableNoMore ()
 
void prepareDataForTriggerSystem (AuraEffect const *triggeredByAura)
 
void AddUnitTarget (Unit *target, uint32 effectMask, bool checkIfValid=true, bool implicit=true)
 
void AddGOTarget (GameObject *target, uint32 effectMask)
 
void AddItemTarget (Item *item, uint32 effectMask)
 
void AddDestTarget (SpellDestination const &dest, uint32 effIndex)
 
void DoAllEffectOnTarget (TargetInfo *target)
 
SpellMissInfo DoSpellHitOnUnit (Unit *unit, uint32 effectMask, bool scaleAura)
 
void DoTriggersOnSpellHit (Unit *unit, uint8 effMask)
 
void DoAllEffectOnTarget (GOTargetInfo *target)
 
void DoAllEffectOnTarget (ItemTargetInfo *target)
 
bool UpdateChanneledTargetList ()
 
bool IsValidDeadOrAliveTarget (Unit const *target) const
 
void HandleLaunchPhase ()
 
void DoAllEffectOnLaunchTarget (TargetInfo &targetInfo, float *multiplier)
 
void PrepareTargetProcessing ()
 
void FinishTargetProcessing ()
 
void InitEffectExecuteData (uint8 effIndex)
 
void CheckEffectExecuteData ()
 
void CallScriptBeforeCastHandlers ()
 
void CallScriptOnCastHandlers ()
 
void CallScriptAfterCastHandlers ()
 
SpellCastResult CallScriptCheckCastHandlers ()
 
void PrepareScriptHitHandlers ()
 
bool CallScriptEffectHandlers (SpellEffIndex effIndex, SpellEffectHandleMode mode)
 
void CallScriptBeforeHitHandlers (SpellMissInfo missInfo)
 
void CallScriptOnHitHandlers ()
 
void CallScriptAfterHitHandlers ()
 
void CallScriptObjectAreaTargetSelectHandlers (std::list< WorldObject * > &targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void CallScriptObjectTargetSelectHandlers (WorldObject *&target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void CallScriptDestinationTargetSelectHandlers (SpellDestination &target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
bool CheckScriptEffectImplicitTargets (uint32 effIndex, uint32 effIndexToCheck)
 
bool CanExecuteTriggersOnHit (uint8 effMask, SpellInfo const *triggeredByAura=nullptr) const
 
void PrepareTriggersExecutedOnHit ()
 
void SummonGuardian (uint32 i, uint32 entry, SummonPropertiesEntry const *properties, uint32 numSummons, bool personalSpawn)
 
void CalculateJumpSpeeds (uint8 i, float dist, float &speedxy, float &speedz)
 
SpellCastResult CanOpenLock (uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
 

Protected Attributes

Unit *const m_caster
 
SpellValue *const m_spellValue
 
ObjectGuid m_originalCasterGUID
 
Unitm_originalCaster
 
Spell ** m_selfContainer
 
SpellSchoolMask m_spellSchoolMask
 
WeaponAttackType m_attackType
 
int32 m_powerCost
 
int32 m_casttime
 
int32 m_channeledDuration
 
bool m_canReflect
 
uint8 m_spellFlags
 
bool m_autoRepeat
 
uint8 m_runesState
 
uint8 m_delayAtDamageCount
 
uint64 m_delayStart
 
uint64 m_delayMoment
 
uint64 m_delayTrajectory
 
bool m_immediateHandled
 
bool m_referencedFromCurrentSpell
 
bool m_executedCurrently
 
bool m_needComboPoints
 
uint8 m_applyMultiplierMask
 
float m_damageMultipliers [3]
 
UnitunitTarget
 
ItemitemTarget
 
GameObjectgameObjTarget
 
WorldLocationdestTarget
 
int32 damage
 
SpellEffectHandleMode effectHandleMode
 
Auram_spellAura
 
DiminishingLevels m_diminishLevel
 
DiminishingGroup m_diminishGroup
 
GameObjectfocusObject
 
int32 m_damage
 
int32 m_healing
 
uint32 m_procAttacker
 
uint32 m_procVictim
 
uint32 m_procEx
 
std::list< TargetInfom_UniqueTargetInfo
 
uint8 m_channelTargetEffectMask
 
std::list< GOTargetInfom_UniqueGOTargetInfo
 
std::list< ItemTargetInfom_UniqueItemInfo
 
SpellDestination m_destTargets [MAX_SPELL_EFFECTS]
 
bool _scriptsLoaded
 
std::list< SpellScript * > m_loadedScripts
 
HitTriggerSpellList m_hitTriggerSpells
 
uint32 m_spellState
 
int32 m_timer
 
SpellEvent_spellEvent
 
TriggerCastFlags _triggeredCastFlags
 
TriggeredByAuraSpellData m_triggeredByAuraSpell
 
bool m_skipCheck
 
uint8 m_auraScaleMask
 
std::unique_ptr< PathGeneratorm_preGeneratedPath
 
bool _spellTargetsSelected
 
ByteBufferm_effectExecuteData [MAX_SPELL_EFFECTS]
 

Friends

class SpellScript
 
void Unit::SetCurrentCastedSpell (Spell *pSpell)
 

Detailed Description

Member Typedef Documentation

◆ HitTriggerSpellList

typedef std::list<HitTriggerSpell> Spell::HitTriggerSpellList
protected

◆ UsedSpellMods

typedef std::set<Aura*> Spell::UsedSpellMods

Constructor & Destructor Documentation

◆ Spell()

Spell::Spell ( Unit caster,
SpellInfo const *  info,
TriggerCastFlags  triggerFlags,
ObjectGuid  originalCasterGUID = ObjectGuid::Empty,
bool  skipCheck = false 
)
571 :
572 m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, caster)),
573 m_caster((info->HasAttribute(SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER) && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster)
575{
577 m_skipCheck = skipCheck;
578 m_selfContainer = nullptr;
580 m_executedCurrently = false;
583 m_comboTarget = nullptr;
584 m_delayStart = 0;
586
588 m_auraScaleMask = 0;
589 memset(m_damageMultipliers, 0, sizeof(m_damageMultipliers));
590
591 // Get data for type of attack
592 switch (m_spellInfo->DmgClass)
593 {
597 else
599 break;
602 break;
603 default:
604 // Wands
607 else
609 break;
610 }
611
612 m_spellSchoolMask = info->GetSchoolMask(); // Can be override for some spell (wand shoot for example)
613
615 // wand case
618 m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetTemplate()->Damage[0].DamageType);
619
620 if (originalCasterGUID)
621 m_originalCasterGUID = originalCasterGUID;
622 else
624
627 else
628 {
631 m_originalCaster = nullptr;
632 }
633
635 _triggeredCastFlags = triggerFlags;
636 if (info->HasAttribute(SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING))
638
639 m_CastItem = nullptr;
640
641 unitTarget = nullptr;
642 itemTarget = nullptr;
643 gameObjTarget = nullptr;
644 destTarget = nullptr;
645 damage = 0;
649 m_damage = 0;
650 m_healing = 0;
651 m_procAttacker = 0;
652 m_procVictim = 0;
653 m_procEx = 0;
654 focusObject = nullptr;
655 m_cast_count = 0;
656 m_glyphIndex = 0;
657 m_preCastSpell = 0;
658 m_spellAura = nullptr;
659 _scriptsLoaded = false;
660
661 //Auto Shot & Shoot (wand)
663
664 m_runesState = 0;
665 m_powerCost = 0; // setup to correct value in Spell::prepare, must not be used before.
666 m_casttime = 0; // setup to correct value in Spell::prepare, must not be used before.
667 m_timer = 0; // will set to castime in prepare
668 m_channeledDuration = 0; // will be setup in Spell::handle_immediate
669 m_immediateHandled = false;
670
672
674
675 // Determine if spell can be reflected back to the caster
676 // Patch 1.2 notes: Spell Reflection no longer reflects abilities
680
682 memset(m_effectExecuteData, 0, MAX_SPELL_EFFECTS * sizeof(ByteBuffer*));
683
684 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
686
687 // xinef:
688 _spellTargetsSelected = false;
689
690 m_weaponItem = nullptr;
691}
#define MAX_SPELL_EFFECTS
Definition DBCStructure.h:1638
std::uint8_t uint8
Definition Define.h:109
std::uint32_t uint32
Definition Define.h:107
@ DIMINISHING_NONE
Definition SharedDefines.h:3508
@ SPELL_EFFECT_DISPEL
Definition SharedDefines.h:827
#define CLASSMASK_WAND_USERS
Definition SharedDefines.h:174
@ SPELL_ATTR2_AUTO_REPEAT
Definition SharedDefines.h:472
@ SPELL_ATTR1_NO_REFLECTION
Definition SharedDefines.h:437
@ SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON
Definition SharedDefines.h:528
@ SPELL_DAMAGE_CLASS_RANGED
Definition SharedDefines.h:1559
@ SPELL_DAMAGE_CLASS_MAGIC
Definition SharedDefines.h:1557
@ SPELL_DAMAGE_CLASS_MELEE
Definition SharedDefines.h:1558
@ SPELL_CUSTOM_ERROR_NONE
Definition SharedDefines.h:1154
@ SPELL_ATTR0_IS_ABILITY
Definition SharedDefines.h:397
@ SPELL_ATTR0_NO_IMMUNITIES
Definition SharedDefines.h:422
@ SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING
Definition SharedDefines.h:548
@ SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER
Definition SharedDefines.h:633
SpellSchoolMask
Definition SharedDefines.h:306
TriggerCastFlags
Definition SpellDefines.h:132
@ TRIGGERED_CAST_DIRECTLY
Will ignore combo point requirement.
Definition SpellDefines.h:141
@ TRIGGERED_IGNORE_CAST_IN_PROGRESS
Will ignore aura scaling.
Definition SpellDefines.h:139
#define sSpellMgr
Definition SpellMgr.h:824
@ SPELL_EFFECT_HANDLE_LAUNCH
Definition Spell.h:243
@ SPELL_FLAG_NORMAL
Definition Spell.h:83
@ SPELL_STATE_NULL
Definition Spell.h:233
@ OFF_ATTACK
Definition Unit.h:211
@ BASE_ATTACK
Definition Unit.h:210
@ RANGED_ATTACK
Definition Unit.h:212
@ DIMINISHING_LEVEL_1
Definition Unit.h:264
Definition ByteBuffer.h:70
Definition Item.h:220
bool IsPlayer() const
Definition Object.h:201
Player * ToPlayer()
Definition Object.h:202
bool IsInWorld() const
Definition Object.h:108
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:113
Item * GetWeaponForAttack(WeaponAttackType attackType, bool useable=false) const
Definition PlayerStorage.cpp:488
bool IsPassive() const
Definition SpellInfo.cpp:1093
bool NeedsComboPoints() const
Definition SpellInfo.cpp:1261
bool HasAttribute(SpellAttr0 attribute) const
Definition SpellInfo.h:415
bool HasEffect(SpellEffects effect) const
Definition SpellInfo.cpp:871
bool IsPositive() const
Definition SpellInfo.cpp:1232
bool IsAutoRepeatRangedSpell() const
Definition SpellInfo.cpp:1278
uint32 DmgClass
Definition SpellInfo.h:390
bool IsRangedWeaponSpell() const
Definition SpellInfo.cpp:1271
Unit * m_comboTarget
Definition Spell.h:565
int8 m_comboPointGain
Definition Spell.h:566
GameObject * gameObjTarget
Definition Spell.h:677
bool m_referencedFromCurrentSpell
Definition Spell.h:668
bool m_canReflect
Definition Spell.h:644
uint32 m_procVictim
Definition Spell.h:699
Unit * m_originalCaster
Definition Spell.h:632
bool m_needComboPoints
Definition Spell.h:670
uint64 m_delayStart
Definition Spell.h:662
bool _scriptsLoaded
Definition Spell.h:750
TriggerCastFlags _triggeredCastFlags
Definition Spell.h:791
int32 damage
Definition Spell.h:679
SpellEffectHandleMode effectHandleMode
Definition Spell.h:680
int32 m_channeledDuration
Definition Spell.h:643
Aura * m_spellAura
Definition Spell.h:682
SpellDestination m_destTargets[MAX_SPELL_EFFECTS]
Definition Spell.h:725
Unit *const m_caster
Definition Spell.h:626
uint8 m_delayAtDamageCount
Definition Spell.h:651
WeaponAttackType m_attackType
Definition Spell.h:640
bool m_immediateHandled
Definition Spell.h:665
uint32 m_spellState
Definition Spell.h:787
ObjectGuid m_originalCasterGUID
Definition Spell.h:630
void CleanupTargetList()
Definition Spell.cpp:2373
int32 m_timer
Definition Spell.h:788
int32 m_casttime
Definition Spell.h:642
Item * itemTarget
Definition Spell.h:676
uint8 m_cast_count
Definition Spell.h:547
int32 m_damage
Definition Spell.h:692
bool m_executedCurrently
Definition Spell.h:669
DiminishingLevels m_diminishLevel
Definition Spell.h:685
float m_damageMultipliers[3]
Definition Spell.h:672
ByteBuffer * m_effectExecuteData[MAX_SPELL_EFFECTS]
Definition Spell.h:805
uint8 m_auraScaleMask
Definition Spell.h:799
SpellCustomErrors m_customError
Definition Spell.h:551
uint8 m_spellFlags
Definition Spell.h:646
bool m_skipCheck
Definition Spell.h:798
int32 m_healing
Definition Spell.h:693
uint32 m_glyphIndex
Definition Spell.h:548
uint8 m_channelTargetEffectMask
Definition Spell.h:707
Item * m_weaponItem
Definition Spell.h:545
Unit * unitTarget
Definition Spell.h:675
SpellSchoolMask m_spellSchoolMask
Definition Spell.h:639
SpellEvent * _spellEvent
Definition Spell.h:790
bool _spellTargetsSelected
Definition Spell.h:803
uint32 m_preCastSpell
Definition Spell.h:549
WorldLocation * destTarget
Definition Spell.h:678
Spell ** m_selfContainer
Definition Spell.h:634
uint8 m_applyMultiplierMask
Definition Spell.h:671
DiminishingGroup m_diminishGroup
Definition Spell.h:686
uint32 m_procEx
Definition Spell.h:700
Item * m_CastItem
Definition Spell.h:544
SpellValue *const m_spellValue
Definition Spell.h:628
int32 m_powerCost
Definition Spell.h:641
uint32 m_procAttacker
Definition Spell.h:698
GameObject * focusObject
Definition Spell.h:689
SpellInfo const *const m_spellInfo
Definition Spell.h:543
uint8 m_runesState
Definition Spell.h:649
bool m_autoRepeat
Definition Spell.h:648
Unit * GetCharmerOrOwner() const
Definition Unit.h:1215
uint32 getClassMask() const
Definition Unit.h:797
Unit * GetUnit(WorldObject const &, ObjectGuid const guid)
Definition ObjectAccessor.cpp:199
Definition Spell.h:103
Definition Spell.h:220

References _scriptsLoaded, _spellTargetsSelected, _triggeredCastFlags, BASE_ATTACK, CLASSMASK_WAND_USERS, CleanupTargetList(), damage, destTarget, DIMINISHING_LEVEL_1, DIMINISHING_NONE, SpellInfo::DmgClass, effectHandleMode, focusObject, gameObjTarget, Unit::getClassMask(), Object::GetGUID(), SpellInfo::GetSchoolMask(), ObjectAccessor::GetUnit(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), SpellInfo::IsAutoRepeatRangedSpell(), Object::IsInWorld(), SpellInfo::IsPassive(), Object::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsRangedWeaponSpell(), itemTarget, m_applyMultiplierMask, m_attackType, m_auraScaleMask, m_autoRepeat, m_canReflect, m_cast_count, m_caster, m_CastItem, m_casttime, m_channeledDuration, m_channelTargetEffectMask, m_comboPointGain, m_comboTarget, m_customError, m_damage, m_damageMultipliers, m_delayAtDamageCount, m_delayStart, m_destTargets, m_diminishGroup, m_diminishLevel, m_effectExecuteData, m_executedCurrently, m_glyphIndex, m_healing, m_immediateHandled, m_needComboPoints, m_originalCaster, m_originalCasterGUID, m_powerCost, m_preCastSpell, m_procAttacker, m_procEx, m_procVictim, m_referencedFromCurrentSpell, m_runesState, m_selfContainer, m_skipCheck, m_spellAura, m_spellFlags, m_spellInfo, m_spellSchoolMask, m_spellState, m_timer, m_weaponItem, MAX_SPELL_EFFECTS, SpellInfo::NeedsComboPoints(), OFF_ATTACK, RANGED_ATTACK, SPELL_ATTR0_IS_ABILITY, SPELL_ATTR0_NO_IMMUNITIES, SPELL_ATTR1_NO_REFLECTION, SPELL_ATTR2_AUTO_REPEAT, SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON, SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING, SPELL_CUSTOM_ERROR_NONE, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_DISPEL, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_FLAG_NORMAL, SPELL_STATE_NULL, Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_CAST_IN_PROGRESS, and unitTarget.

Referenced by Creature::HasSpellFocus().

◆ ~Spell()

Spell::~Spell ( )
694{
695 // unload scripts
696 while (!m_loadedScripts.empty())
697 {
698 std::list<SpellScript*>::iterator itr = m_loadedScripts.begin();
699 (*itr)->_Unload();
700 delete (*itr);
701 m_loadedScripts.erase(itr);
702 }
703
705 {
706 // Clean the reference to avoid later crash.
707 // If this error is repeating, we may have to add an ASSERT to better track down how we get into this case.
708 LOG_ERROR("spells", "Spell::~Spell: deleting spell for spell ID {}. However, spell still referenced.", m_spellInfo->Id);
709 *m_selfContainer = nullptr;
710 }
711
712 delete m_spellValue;
713
715}
#define LOG_ERROR(filterType__,...)
Definition Log.h:158
uint32 Id
Definition SpellInfo.h:321
void CheckEffectExecuteData()
Definition Spell.cpp:8545
std::list< SpellScript * > m_loadedScripts
Definition Spell.h:765

References CheckEffectExecuteData(), SpellInfo::Id, LOG_ERROR, m_loadedScripts, m_referencedFromCurrentSpell, m_selfContainer, m_spellInfo, and m_spellValue.

Member Function Documentation

◆ _cast()

void Spell::_cast ( bool  skipCheck)

Not own traded item (in trader trade slot) req. reagents including triggered spell case

3818{
3819 // update pointers base at GUIDs to prevent access to non-existed already object
3820 if (!UpdatePointers())
3821 {
3822 // cancel the spell if UpdatePointers() returned false, something wrong happened there
3823 cancel();
3824 return;
3825 }
3826
3827 // cancel at lost explicit target during cast
3829 {
3830 cancel();
3831 return;
3832 }
3833
3834 // Xinef: implement attribute SPELL_ATTR1_DISMISS_PET_FIRST, on spell cast current pet is dismissed and charms are removed
3836 {
3838 if (Pet* pet = m_caster->ToPlayer()->GetPet())
3840
3841 if (Unit* charm = m_caster->GetCharm())
3842 charm->RemoveAurasByType(SPELL_AURA_MOD_CHARM, m_caster->GetGUID());
3843 }
3844
3845 if (Player* playerCaster = m_caster->ToPlayer())
3846 {
3847 // now that we've done the basic check, now run the scripts
3848 // should be done before the spell is actually executed
3849 sScriptMgr->OnPlayerSpellCast(playerCaster, this, skipCheck);
3850
3851 // As of 3.0.2 pets begin attacking their owner's target immediately
3852 // Let any pets know we've attacked something. Check DmgClass for harmful spells only
3853 // This prevents spells such as Hunter's Mark from triggering pet attack
3854 // xinef: take into account SPELL_ATTR3_SUPPRESS_TARGET_PROCS
3856 if (!playerCaster->m_Controlled.empty())
3857 for (Unit::ControlSet::iterator itr = playerCaster->m_Controlled.begin(); itr != playerCaster->m_Controlled.end(); ++itr)
3858 if (Unit* pet = *itr)
3859 if (pet->IsAlive() && pet->IsCreature())
3860 pet->ToCreature()->AI()->OwnerAttacked(m_targets.GetUnitTarget());
3861 }
3862
3864
3868
3870
3871 Player* modOwner = m_caster->GetSpellModOwner();
3872 // skip check if done already (for instant cast spells for example)
3873 if (!skipCheck)
3874 {
3875 SpellCastResult castResult = CheckCast(false);
3876 if (castResult != SPELL_CAST_OK)
3877 {
3878 SendCastResult(castResult);
3879 SendInterrupted(0);
3880
3881 finish(false);
3882 SetExecutedCurrently(false);
3883 return;
3884 }
3885
3886 // additional check after cast bar completes (must not be in CheckCast)
3887 // if trade not complete then remember it in trade data
3889 {
3890 if (m_caster->IsPlayer())
3891 {
3892 if (TradeData* my_trade = m_caster->ToPlayer()->GetTradeData())
3893 {
3894 if (!my_trade->IsInAcceptProcess())
3895 {
3896 // Spell will be casted at completing the trade. Silently ignore at this place
3897 my_trade->SetSpell(m_spellInfo->Id, m_CastItem);
3899 SendInterrupted(0);
3900
3901 finish(false);
3902 SetExecutedCurrently(false);
3903 return;
3904 }
3905 }
3906 }
3907 }
3908 }
3909
3910 if (modOwner)
3911 modOwner->SetSpellModTakingSpell(this, true);
3912
3915
3916 if (modOwner)
3917 modOwner->SetSpellModTakingSpell(this, false);
3918
3919 // Spell may be finished after target map check
3921 {
3922 SendInterrupted(0);
3923 finish(false);
3924 SetExecutedCurrently(false);
3925 return;
3926 }
3927
3928 if (modOwner)
3929 modOwner->SetSpellModTakingSpell(this, true);
3930
3932
3934
3935 if (modOwner)
3936 modOwner->SetSpellModTakingSpell(this, false);
3937
3938 // traded items have trade slot instead of guid in m_itemTargetGUID
3939 // set to real guid to be sent later to the client
3941
3942 if (m_caster->IsPlayer())
3943 {
3945 {
3948 }
3949
3951 }
3952
3954 {
3955 // Powers have to be taken before SendSpellGo
3956 TakePower();
3957 TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
3958 }
3959 else if (Item* targetItem = m_targets.GetItemTarget())
3960 {
3962 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
3963 TakeReagents();
3964 }
3965
3967
3968 // CAST SPELL
3969 if (modOwner)
3970 modOwner->SetSpellModTakingSpell(this, true);
3971
3973
3975
3976 // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
3977 SendSpellGo();
3978
3979 if (modOwner)
3980 modOwner->SetSpellModTakingSpell(this, false);
3981
3982 if (m_originalCaster)
3983 {
3984 // Handle procs on cast
3985 uint32 procAttacker = m_procAttacker;
3986 if (!procAttacker)
3987 {
3988 bool IsPositive = m_spellInfo->IsPositive();
3990 {
3992 }
3993 else
3994 {
3996 }
3997 }
3998
3999 uint32 procEx = PROC_EX_NORMAL_HIT;
4000
4001 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4002 {
4003 if (ihit->missCondition != SPELL_MISS_NONE)
4004 {
4005 continue;
4006 }
4007
4008 if (!ihit->crit)
4009 {
4010 continue;
4011 }
4012
4013 procEx |= PROC_EX_CRITICAL_HIT;
4014 break;
4015 }
4016
4019 }
4020
4021 if (modOwner)
4022 modOwner->SetSpellModTakingSpell(this, true);
4023
4025 if (resetAttackTimers)
4026 {
4028 for (Unit::AuraEffectList::const_iterator i = vIgnoreReset.begin(); i != vIgnoreReset.end(); ++i)
4029 {
4030 if ((*i)->IsAffectedOnSpell(m_spellInfo))
4031 {
4032 resetAttackTimers = false;
4033 break;
4034 }
4035 }
4036 }
4037
4038 // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
4039 if ((m_spellInfo->Speed > 0.0f && !m_spellInfo->IsChanneled())/* xinef: we dont need this || m_spellInfo->Id == 14157*/)
4040 {
4041 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4042 // in case delayed spell remove item at cast delay start
4043 TakeCastItem();
4044
4045 // Okay, maps created, now prepare flags
4046 m_immediateHandled = false;
4048 SetDelayStart(0);
4049
4052
4053 // remove all applied mods at this point
4054 // dont allow user to use them twice in case spell did not reach current target
4055 if (modOwner)
4056 modOwner->RemoveSpellMods(this);
4057
4058 // Xinef: why do we keep focus after spell is sent to air?
4059 // Xinef: Because of this, in the middle of some animation after setting targetguid to 0 etc
4060 // Xinef: we get focused to it out of nowhere...
4061 if (Creature* creatureCaster = m_caster->ToCreature())
4062 creatureCaster->ReleaseFocus(this);
4063 }
4064 else
4065 {
4066 // Immediate spell, no big deal
4068 }
4069
4070 if (resetAttackTimers)
4071 {
4072 if (m_casttime == 0 && m_spellInfo->CalcCastTime())
4073 {
4074 resetAttackTimers = false;
4075 }
4076
4077 if (resetAttackTimers)
4078 {
4080
4082 {
4084 }
4085
4087 }
4088 }
4089
4091
4092 if (modOwner)
4093 modOwner->SetSpellModTakingSpell(this, false);
4094
4095 if (std::vector<int32> const* spell_triggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id))
4096 {
4097 for (int32 id : *spell_triggered)
4098 {
4099 if (id < 0)
4101 else
4103 }
4104 }
4105
4106 // Interrupt Spell casting
4107 // handle this here, in other places SpellHitTarget can be set to nullptr, if there is an error in this function
4109 if (Unit* target = m_targets.GetUnitTarget())
4110 if (target->IsCreature())
4111 m_caster->CastSpell(target, 32747, true);
4112
4113 // xinef: start combat at cast for delayed spells, only for explicit target
4114 if (Unit* target = m_targets.GetUnitTarget())
4117 m_caster->CombatStartOnCast(target, !m_spellInfo->HasAttribute(SPELL_ATTR3_SUPPRESS_TARGET_PROCS), GetDelayMoment() + 500); // xinef: increase this time so we dont leave and enter combat in a moment
4118
4119 if (m_caster->IsPlayer())
4122
4123 sScriptMgr->OnSpellCast(this, m_caster, m_spellInfo, skipCheck);
4124
4125 SetExecutedCurrently(false);
4126
4127 // Call CreatureAI hook OnSpellCastFinished
4128 if (m_originalCaster)
4129 if (Creature* caster = m_originalCaster->ToCreature())
4130 if (caster->IsAIEnabled)
4131 caster->AI()->OnSpellCastFinished(GetSpellInfo(), SPELL_FINISHED_SUCCESSFUL_CAST);
4132}
@ ACHIEVEMENT_TIMED_TYPE_ITEM
Definition DBCEnums.h:115
@ ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM
Definition DBCEnums.h:155
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL
Definition DBCEnums.h:143
std::int32_t int32
Definition Define.h:103
@ PET_SAVE_AS_CURRENT
Definition PetDefines.h:42
@ CHEAT_COOLDOWN
Definition Player.h:997
#define sScriptMgr
Definition ScriptMgr.h:728
@ SPELL_ATTR7_CAN_CAUSE_INTERRUPT
Definition SharedDefines.h:663
@ SPELL_EFFECT_SUMMON_PET
Definition SharedDefines.h:845
@ SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS
Definition SharedDefines.h:484
@ SPELL_ATTR1_DISMISS_PET_FIRST
Definition SharedDefines.h:430
@ SPELL_ATTR3_SUPPRESS_TARGET_PROCS
Definition SharedDefines.h:521
@ SPELL_DAMAGE_CLASS_NONE
Definition SharedDefines.h:1556
@ SPELL_MISS_NONE
Definition SharedDefines.h:1530
SpellCastResult
Definition SharedDefines.h:959
@ SPELL_FAILED_DONT_REPORT
Definition SharedDefines.h:987
@ SPELL_CAST_OK
Definition SharedDefines.h:1149
@ SPELL_AURA_MOD_CHARM
Definition SpellAuraDefines.h:69
@ SPELL_AURA_IGNORE_MELEE_RESET
Definition SpellAuraDefines.h:335
@ SPELL_AURA_BIND_SIGHT
Definition SpellAuraDefines.h:64
@ TRIGGERED_IGNORE_POWER_AND_REAGENT_COST
Will ignore Spell and Category cooldowns.
Definition SpellDefines.h:136
@ TRIGGERED_IGNORE_CAST_ITEM
Will ignore power and reagent cost.
Definition SpellDefines.h:137
@ TRIGGERED_IGNORE_SET_FACING
Will ignore interruptible aura's at cast.
Definition SpellDefines.h:143
@ TARGET_FLAG_TRADE_ITEM
Definition SpellInfo.h:59
@ TARGET_FLAG_UNIT
Definition SpellInfo.h:48
@ PROC_EX_CRITICAL_HIT
Definition SpellMgr.h:195
@ PROC_EX_NORMAL_HIT
Definition SpellMgr.h:194
@ PROC_SPELL_PHASE_CAST
Definition SpellMgr.h:243
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS
Definition SpellMgr.h:128
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS
Definition SpellMgr.h:122
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG
Definition SpellMgr.h:125
@ PROC_FLAG_NONE
Definition SpellMgr.h:105
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG
Definition SpellMgr.h:131
@ SPELL_FINISHED_SUCCESSFUL_CAST
Definition Spell.h:97
@ SPELL_STATE_DELAYED
Definition Spell.h:238
@ SPELL_STATE_FINISHED
Definition Spell.h:236
@ UNIT_STATE_CASTING
Definition UnitDefines.h:185
Definition Creature.h:43
uint32 GetEntry() const
Definition Object.h:116
bool IsCreature() const
Definition Object.h:205
Creature * ToCreature()
Definition Object.h:206
Definition Pet.h:41
Definition Player.h:1072
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, Unit *unit=nullptr)
Definition PlayerUpdates.cpp:2167
void SetSpellModTakingSpell(Spell *spell, bool apply)
Definition Player.cpp:10124
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost=0)
Definition Player.cpp:13950
void RemoveSpellMods(Spell *spell)
Definition Player.cpp:10046
Pet * GetPet() const
Definition Player.cpp:8994
bool GetCommandStatus(uint32 command) const
Definition Player.h:1189
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition Player.cpp:9144
TradeData * GetTradeData() const
Definition Player.h:1381
void RemoveSpellCooldown(uint32 spell_id, bool update=false)
Definition Player.cpp:3548
WorldObject * GetObjectTarget() const
Definition Spell.cpp:311
void UpdateTradeSlotItem()
Definition Spell.cpp:348
ObjectGuid GetObjectTargetGUID() const
Definition Spell.cpp:316
Item * GetItemTarget() const
Definition Spell.h:148
uint32 GetTargetMask() const
Definition Spell.h:126
Unit * GetUnitTarget() const
Definition Spell.cpp:232
float Speed
Definition SpellInfo.h:371
bool IsChanneled() const
Definition SpellInfo.cpp:1251
uint32 CalcCastTime(Unit *caster=nullptr, Spell *spell=nullptr) const
Definition SpellInfo.cpp:2359
bool HasAura(AuraType aura) const
Definition SpellInfo.cpp:888
SpellInfo const * GetSpellInfo() const
Definition Spell.h:599
void CallScriptAfterCastHandlers()
Definition Spell.cpp:8599
void PrepareTriggersExecutedOnHit()
Definition Spell.cpp:8805
bool HasTriggeredCastFlag(TriggerCastFlags flag) const
Definition Spell.h:577
SpellCastTargets m_targets
Definition Spell.h:550
TriggeredByAuraSpellData m_triggeredByAuraSpell
Definition Spell.h:796
void handle_immediate()
Definition Spell.cpp:4134
void SendSpellGo()
Definition Spell.cpp:4826
void TakeReagents()
Definition Spell.cpp:5561
void SetExecutedCurrently(bool yes)
Definition Spell.h:585
void SendInterrupted(uint8 result)
Definition Spell.cpp:5203
void PrepareScriptHitHandlers()
Definition Spell.cpp:8631
void CallScriptOnCastHandlers()
Definition Spell.cpp:8586
void cancel(bool bySelf=false)
Definition Spell.cpp:3727
void SendSpellCooldown()
Definition Spell.cpp:4374
void CallScriptBeforeCastHandlers()
Definition Spell.cpp:8573
void HandleLaunchPhase()
Definition Spell.cpp:8276
bool UpdatePointers()
Definition Spell.cpp:7906
void SetDelayStart(uint64 m_time)
Definition Spell.h:587
std::list< TargetInfo > m_UniqueTargetInfo
Definition Spell.h:706
void SelectSpellTargets()
Definition Spell.cpp:819
void TakePower()
Definition Spell.cpp:5344
SpellCastResult CheckCast(bool strict)
Definition Spell.cpp:5683
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
Definition Spell.cpp:4698
uint64 GetDelayMoment() const
Definition Spell.h:588
void TakeCastItem()
Definition Spell.cpp:5281
bool IsAutoActionResetSpell() const
Definition Spell.cpp:8120
void finish(bool ok=true)
Definition Spell.cpp:4506
Definition TradeData.h:36
Definition Unit.h:620
bool HasOffhandWeaponForAttack() const
Definition Unit.h:931
void ClearUnitState(uint32 f)
Definition Unit.h:692
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition Unit.h:1353
Unit * GetCharm() const
Definition Unit.cpp:10766
std::vector< AuraEffect * > AuraEffectList
Definition Unit.h:636
Player * GetSpellModOwner() const
Definition Unit.cpp:16660
void CombatStartOnCast(Unit *target, bool initialAggro=true, uint32 duration=0)
Definition Unit.cpp:13800
bool IsPet() const
Definition Unit.h:749
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition Unit.cpp:4155
SpellCastResult CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition Unit.cpp:1194
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:4974
static void ProcDamageAndSpell(Unit *actor, Unit *victim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType=BASE_ATTACK, SpellInfo const *procSpellInfo=nullptr, SpellInfo const *procAura=nullptr, int8 procAuraEffectIndex=-1, Spell const *procSpell=nullptr, DamageInfo *damageInfo=nullptr, HealInfo *healInfo=nullptr, uint32 procPhase=2)
Definition Unit.cpp:6474
bool HasUnitState(const uint32 f) const
Definition Unit.h:691
bool IsFriendlyTo(Unit const *unit) const
Definition Unit.cpp:10311
bool IsControlledByPlayer() const
Definition Unit.h:1236
void SetInFront(WorldObject const *target)
Definition Unit.cpp:20363
void resetAttackTimer(WeaponAttackType type=BASE_ATTACK)
Definition Unit.cpp:644
int8 effectIndex
Definition Spell.h:289
SpellInfo const * spellInfo
Definition Spell.h:288

References _spellTargetsSelected, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, ACHIEVEMENT_TIMED_TYPE_ITEM, BASE_ATTACK, SpellInfo::CalcCastTime(), CallScriptAfterCastHandlers(), CallScriptBeforeCastHandlers(), CallScriptOnCastHandlers(), cancel(), Unit::CastSpell(), CHEAT_COOLDOWN, CheckCast(), Unit::ClearUnitState(), Unit::CombatStartOnCast(), SpellInfo::DmgClass, TriggeredByAuraSpellData::effectIndex, finish(), Unit::GetAuraEffectsByType(), Unit::GetCharm(), Player::GetCommandStatus(), GetDelayMoment(), Object::GetEntry(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetObjectTarget(), SpellCastTargets::GetObjectTargetGUID(), Player::GetPet(), GetSpellInfo(), Unit::GetSpellModOwner(), SpellCastTargets::GetTargetMask(), Player::GetTradeData(), SpellCastTargets::GetUnitTarget(), handle_immediate(), HandleLaunchPhase(), SpellInfo::HasAttribute(), SpellInfo::HasAura(), SpellInfo::HasEffect(), Unit::HasOffhandWeaponForAttack(), HasTriggeredCastFlag(), Unit::HasUnitState(), SpellInfo::Id, IsAutoActionResetSpell(), SpellInfo::IsChanneled(), Unit::IsControlledByPlayer(), Object::IsCreature(), Unit::IsFriendlyTo(), Unit::IsNonMeleeSpellCast(), Unit::IsPet(), Object::IsPlayer(), SpellInfo::IsPositive(), m_caster, m_CastItem, m_casttime, m_immediateHandled, m_originalCaster, m_procAttacker, m_spellInfo, m_spellState, m_targets, m_triggeredByAuraSpell, m_UniqueTargetInfo, OFF_ATTACK, PET_SAVE_AS_CURRENT, PrepareScriptHitHandlers(), PrepareTriggersExecutedOnHit(), PROC_EX_CRITICAL_HIT, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_NONE, PROC_SPELL_PHASE_CAST, Unit::ProcDamageAndSpell(), RANGED_ATTACK, Unit::RemoveAurasDueToSpell(), Player::RemovePet(), Player::RemoveSpellCooldown(), Player::RemoveSpellMods(), Unit::resetAttackTimer(), SelectSpellTargets(), SendCastResult(), SendInterrupted(), SendSpellCooldown(), SendSpellGo(), SetDelayStart(), SetExecutedCurrently(), Unit::SetInFront(), Player::SetSpellModTakingSpell(), SpellInfo::Speed, SPELL_ATTR1_DISMISS_PET_FIRST, SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS, SPELL_ATTR3_SUPPRESS_TARGET_PROCS, SPELL_ATTR7_CAN_CAUSE_INTERRUPT, SPELL_AURA_BIND_SIGHT, SPELL_AURA_IGNORE_MELEE_RESET, SPELL_AURA_MOD_CHARM, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_NONE, SPELL_EFFECT_DISPEL, SPELL_EFFECT_SUMMON_PET, SPELL_FAILED_DONT_REPORT, SPELL_FINISHED_SUCCESSFUL_CAST, SPELL_MISS_NONE, SPELL_STATE_DELAYED, SPELL_STATE_FINISHED, TriggeredByAuraSpellData::spellInfo, sScriptMgr, sSpellMgr, Player::StartTimedAchievement(), TakeCastItem(), TakePower(), TakeReagents(), TARGET_FLAG_TRADE_ITEM, TARGET_FLAG_UNIT, Object::ToCreature(), Object::ToPlayer(), TRIGGERED_IGNORE_CAST_ITEM, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, TRIGGERED_IGNORE_SET_FACING, UNIT_STATE_CASTING, Player::UpdateAchievementCriteria(), UpdatePointers(), and SpellCastTargets::UpdateTradeSlotItem().

Referenced by cast().

◆ _handle_finish_phase()

void Spell::_handle_finish_phase ( )
4300{
4301 // Take for real after all targets are processed
4303 {
4305 }
4306
4307 // Real add combo points from effects
4309 {
4310 // remove Premed-like effects unless they were caused by ourselves
4311 // (this Aura removes the already-added CP when it expires from duration - now that we've added CP, this shouldn't happen anymore!)
4313 {
4315 }
4316
4318 }
4319
4321 {
4323 }
4324
4327 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4328 {
4329 // Xinef: Properly clear infinite cooldowns in some cases
4330 if (ihit->targetGUID == m_caster->GetGUID() && ihit->missCondition != SPELL_MISS_NONE)
4333 }
4334
4335 // Handle procs on finish
4336 if (m_originalCaster)
4337 {
4338 uint32 procAttacker = m_procAttacker;
4339 if (!procAttacker)
4340 {
4341 bool IsPositive = m_spellInfo->IsPositive();
4343 {
4345 }
4346 else
4347 {
4349 }
4350 }
4351
4352 uint32 procEx = PROC_EX_NORMAL_HIT;
4353 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4354 {
4355 if (ihit->missCondition != SPELL_MISS_NONE)
4356 {
4357 continue;
4358 }
4359
4360 if (!ihit->crit)
4361 {
4362 continue;
4363 }
4364
4365 procEx |= PROC_EX_CRITICAL_HIT;
4366 break;
4367 }
4368
4371 }
4372}
@ SPELL_EFFECT_ADD_EXTRA_ATTACKS
Definition SharedDefines.h:808
@ SPELL_AURA_RETAIN_COMBO_POINTS
Definition SpellAuraDefines.h:211
@ PROC_SPELL_PHASE_FINISH
Definition SpellMgr.h:245
void SendCooldownEvent(SpellInfo const *spellInfo, uint32 itemId=0, Spell *spell=nullptr, bool setCooldown=true)
Definition Player.cpp:11144
bool IsCooldownStartedOnEvent() const
Definition SpellInfo.cpp:1207
bool IsAutoRepeat() const
Definition Spell.h:571
bool IsNextMeleeSwingSpell() const
Definition Spell.cpp:8110
void SetLastExtraAttackSpell(uint32 spellId)
Definition Unit.h:950
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition Unit.cpp:10711
void ClearComboPoints()
Definition Unit.cpp:16947
void AddComboPoints(Unit *target, int8 count)
Definition Unit.cpp:16921
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID=ObjectGuid::Empty, Aura *except=nullptr, bool negative=true, bool positive=true)
Definition Unit.cpp:5175

References Unit::AddComboPoints(), BASE_ATTACK, Unit::ClearComboPoints(), SpellInfo::DmgClass, TriggeredByAuraSpellData::effectIndex, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), Object::GetGUID(), SpellInfo::HasAura(), SpellInfo::HasEffect(), SpellInfo::Id, IsAutoRepeat(), SpellInfo::IsCooldownStartedOnEvent(), IsNextMeleeSwingSpell(), Object::IsPlayer(), SpellInfo::IsPositive(), m_caster, m_comboPointGain, m_comboTarget, m_needComboPoints, m_originalCaster, m_procAttacker, m_spellInfo, m_triggeredByAuraSpell, m_UniqueTargetInfo, PROC_EX_CRITICAL_HIT, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_NONE, PROC_SPELL_PHASE_FINISH, Unit::ProcDamageAndSpell(), Unit::RemoveAurasByType(), Player::SendCooldownEvent(), Unit::SetLastExtraAttackSpell(), SPELL_AURA_RETAIN_COMBO_POINTS, SPELL_DAMAGE_CLASS_MAGIC, SPELL_EFFECT_ADD_EXTRA_ATTACKS, SPELL_MISS_NONE, TriggeredByAuraSpellData::spellInfo, and Object::ToPlayer().

Referenced by handle_delayed(), and handle_immediate().

◆ _handle_immediate_phase()

void Spell::_handle_immediate_phase ( )
4272{
4273 m_spellAura = nullptr;
4274 // initialize Diminishing Returns Data
4277
4278 // handle some immediate features of the spell here
4280
4282
4283 // handle effects with SPELL_EFFECT_HANDLE_HIT mode
4284 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4285 {
4286 // don't do anything for empty effect
4287 if (!m_spellInfo->Effects[j].IsEffect())
4288 continue;
4289
4290 // call effect handlers to handle destination hit
4291 HandleEffects(nullptr, nullptr, nullptr, j, SPELL_EFFECT_HANDLE_HIT);
4292 }
4293
4294 // process items
4295 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
4296 DoAllEffectOnTarget(&(*ihit));
4297}
@ SPELL_EFFECT_HANDLE_HIT
Definition Spell.h:245
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition SpellInfo.h:394
void HandleThreatSpells()
Definition Spell.cpp:5610
void HandleEffects(Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
Definition Spell.cpp:5657
std::list< ItemTargetInfo > m_UniqueItemInfo
Definition Spell.h:723
void DoAllEffectOnTarget(TargetInfo *target)
Definition Spell.cpp:2611

References DIMINISHING_LEVEL_1, DIMINISHING_NONE, DoAllEffectOnTarget(), SpellInfo::Effects, HandleEffects(), HandleThreatSpells(), m_diminishGroup, m_diminishLevel, m_spellAura, m_spellInfo, m_UniqueItemInfo, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), and SPELL_EFFECT_HANDLE_HIT.

Referenced by handle_delayed(), and handle_immediate().

◆ AddComboPointGain()

void Spell::AddComboPointGain ( Unit target,
int8  amount 
)
inline
554 {
555 if (target != m_comboTarget)
556 {
557 m_comboTarget = target;
558 m_comboPointGain = amount;
559 }
560 else
561 {
562 m_comboPointGain += amount;
563 }
564 }

References m_comboPointGain, and m_comboTarget.

Referenced by EffectAddComboPoints(), and EffectWeaponDmg().

◆ AddDestTarget()

void Spell::AddDestTarget ( SpellDestination const &  dest,
uint32  effIndex 
)
protected
2607{
2608 m_destTargets[effIndex] = dest;
2609}

References m_destTargets.

Referenced by SelectSpellTargets().

◆ AddGOTarget()

void Spell::AddGOTarget ( GameObject target,
uint32  effectMask 
)
protected
2516{
2517 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2518 {
2519 if (!m_spellInfo->Effects[effIndex].IsEffect())
2520 effectMask &= ~(1 << effIndex);
2521 else
2522 {
2523 switch (m_spellInfo->Effects[effIndex].Effect)
2524 {
2528 if (go->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
2529 effectMask &= ~(1 << effIndex);
2530 break;
2531 default:
2532 break;
2533 }
2534 }
2535 }
2536
2537 if (!effectMask)
2538 return;
2539
2540 ObjectGuid targetGUID = go->GetGUID();
2541
2542 // Lookup target in already in list
2543 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
2544 {
2545 if (targetGUID == ihit->targetGUID) // Found in list
2546 {
2547 ihit->effectMask |= effectMask; // Add only effect mask
2548 return;
2549 }
2550 }
2551
2552 // This is new target calculate data for him
2553
2554 GOTargetInfo target;
2555 target.targetGUID = targetGUID;
2556 target.effectMask = effectMask;
2557 target.processed = false; // Effects not apply on target
2558
2559 // Spell have speed - need calculate incoming time
2560 if (m_spellInfo->Speed > 0.0f)
2561 {
2562 // calculate spell incoming interval
2563 float dist = m_caster->GetDistance(go->GetPositionX(), go->GetPositionY(), go->GetPositionZ());
2564 if (dist < 5.0f)
2565 dist = 5.0f;
2566 target.timeDelay = uint64(std::floor(dist / m_spellInfo->Speed * 1000.0f));
2567 if (m_delayMoment == 0 || m_delayMoment > target.timeDelay)
2568 m_delayMoment = target.timeDelay;
2569 }
2570 else
2571 target.timeDelay = 0LL;
2572
2573 // Add target to list
2574 m_UniqueGOTargetInfo.push_back(target);
2575}
std::uint64_t uint64
Definition Define.h:106
@ GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING
Definition SharedDefines.h:1604
@ SPELL_EFFECT_GAMEOBJECT_REPAIR
Definition SharedDefines.h:877
@ SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE
Definition SharedDefines.h:878
@ SPELL_EFFECT_GAMEOBJECT_DAMAGE
Definition SharedDefines.h:876
Definition ObjectGuid.h:118
uint64 m_delayMoment
Definition Spell.h:663
std::list< GOTargetInfo > m_UniqueGOTargetInfo
Definition Spell.h:716
float GetDistance(WorldObject const *obj) const
Definition Object.cpp:1250

References Spell::GOTargetInfo::effectMask, SpellInfo::Effects, GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING, WorldObject::GetDistance(), GameObject::GetGoType(), Object::GetGUID(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), m_caster, m_delayMoment, m_spellInfo, m_UniqueGOTargetInfo, MAX_SPELL_EFFECTS, Spell::GOTargetInfo::processed, SpellInfo::Speed, SPELL_EFFECT_GAMEOBJECT_DAMAGE, SPELL_EFFECT_GAMEOBJECT_REPAIR, SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE, Spell::GOTargetInfo::targetGUID, and Spell::GOTargetInfo::timeDelay.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitConeTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ AddItemTarget()

void Spell::AddItemTarget ( Item item,
uint32  effectMask 
)
protected
2578{
2579 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2580 if (!m_spellInfo->Effects[effIndex].IsEffect())
2581 effectMask &= ~(1 << effIndex);
2582
2583 // no effects left
2584 if (!effectMask)
2585 return;
2586
2587 // Lookup target in already in list
2588 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
2589 {
2590 if (item == ihit->item) // Found in list
2591 {
2592 ihit->effectMask |= effectMask; // Add only effect mask
2593 return;
2594 }
2595 }
2596
2597 // This is new target add data
2598
2599 ItemTargetInfo target;
2600 target.item = item;
2601 target.effectMask = effectMask;
2602
2603 m_UniqueItemInfo.push_back(target);
2604}

References Spell::ItemTargetInfo::effectMask, SpellInfo::Effects, Spell::ItemTargetInfo::item, m_spellInfo, m_UniqueItemInfo, and MAX_SPELL_EFFECTS.

Referenced by SelectEffectTypeImplicitTargets(), and SelectImplicitTargetObjectTargets().

◆ AddUnitTarget()

void Spell::AddUnitTarget ( Unit target,
uint32  effectMask,
bool  checkIfValid = true,
bool  implicit = true 
)
protected
Todo:
: this is a hack
Todo:
: seduction should be casted only on humanoids (not demons)
2383{
2384 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2385 if (!m_spellInfo->Effects[effIndex].IsEffect() || !CheckEffectTarget(target, effIndex))
2386 effectMask &= ~(1 << effIndex);
2387
2388 // no effects left
2389 if (!effectMask)
2390 return;
2391
2392 if (checkIfValid)
2393 {
2394 SpellCastResult res = m_spellInfo->CheckTarget(m_caster, target, implicit);
2395 if (res != SPELL_CAST_OK)
2396 return;
2397 }
2398
2399 // Check for effect immune skip if immuned
2400 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2401 if (target->IsImmunedToSpellEffect(m_spellInfo, effIndex))
2402 effectMask &= ~(1 << effIndex);
2403
2404 ObjectGuid targetGUID = target->GetGUID();
2405
2406 // Lookup target in already in list
2407 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
2408 {
2409 if (targetGUID == ihit->targetGUID) // Found in list
2410 {
2411 ihit->effectMask |= effectMask; // Immune effects removed from mask
2412 ihit->scaleAura = false;
2413 if (m_auraScaleMask && ihit->effectMask == m_auraScaleMask && m_caster != target)
2414 {
2415 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2416 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2417 ihit->scaleAura = true;
2418 }
2419
2420 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, *ihit);
2421 return;
2422 }
2423 }
2424
2425 // This is new target calculate data for him
2426
2427 // Get spell hit result on target
2428 TargetInfo targetInfo;
2429 targetInfo.targetGUID = targetGUID; // Store target GUID
2430 targetInfo.effectMask = effectMask; // Store all effects not immune
2431 targetInfo.processed = false; // Effects not apply on target
2432 targetInfo.alive = target->IsAlive();
2433 targetInfo.damage = 0;
2434 targetInfo.crit = false;
2435 targetInfo.scaleAura = false;
2436 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask && m_caster != target)
2437 {
2438 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2439 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2440 targetInfo.scaleAura = true;
2441 }
2442
2443 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, targetInfo);
2444
2445 // Calculate hit result
2446 if (m_originalCaster)
2447 {
2448 targetInfo.missCondition = m_originalCaster->SpellHitResult(target, this, m_canReflect);
2449 if (m_skipCheck && targetInfo.missCondition != SPELL_MISS_IMMUNE)
2450 {
2451 targetInfo.missCondition = SPELL_MISS_NONE;
2452 }
2453 }
2454 else
2455 targetInfo.missCondition = SPELL_MISS_EVADE; //SPELL_MISS_NONE;
2456
2457 // Spell have speed - need calculate incoming time
2458 // Incoming time is zero for self casts. At least I think so.
2459 if (m_spellInfo->Speed > 0.0f && m_caster != target)
2460 {
2461 // calculate spell incoming interval
2463 float dist = m_caster->GetDistance(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
2464
2465 if (dist < 5.0f)
2466 dist = 5.0f;
2467 targetInfo.timeDelay = (uint64) std::floor(dist / m_spellInfo->Speed * 1000.0f);
2468
2469 // Calculate minimum incoming time
2470 if (m_delayMoment == 0 || m_delayMoment > targetInfo.timeDelay)
2471 m_delayMoment = targetInfo.timeDelay;
2472 }
2473 else
2474 targetInfo.timeDelay = 0LL;
2475
2476 // If target reflect spell back to caster
2477 if (targetInfo.missCondition == SPELL_MISS_REFLECT)
2478 {
2479 // Calculate reflected spell result on caster
2481
2482 if (targetInfo.reflectResult == SPELL_MISS_REFLECT) // Impossible reflect again, so simply deflect spell
2483 targetInfo.reflectResult = SPELL_MISS_PARRY;
2484
2485 // Increase time interval for reflected spells by 1.5
2487 targetInfo.timeDelay += targetInfo.timeDelay >> 1;
2488
2490
2491 // HACK: workaround check for succubus seduction case
2493 if (m_caster->IsPet())
2494 {
2495 CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(m_caster->GetEntry());
2496 switch (ci->family)
2497 {
2499 {
2500 if (m_spellInfo->SpellIconID != 694) // Soothing Kiss
2501 cancel();
2502 }
2503 break;
2504 return;
2505 }
2506 }
2507 }
2508 else
2509 targetInfo.reflectResult = SPELL_MISS_NONE;
2510
2511 // Add target to list
2512 m_UniqueTargetInfo.push_back(targetInfo);
2513}
#define sObjectMgr
Definition ObjectMgr.h:1650
@ CREATURE_FAMILY_SUCCUBUS
Definition SharedDefines.h:2675
@ SPELL_MISS_PARRY
Definition SharedDefines.h:1534
@ SPELL_MISS_IMMUNE
Definition SharedDefines.h:1537
@ SPELL_MISS_EVADE
Definition SharedDefines.h:1536
@ SPELL_MISS_REFLECT
Definition SharedDefines.h:1541
@ SPELL_FLAG_REFLECTED
Definition Spell.h:84
void AddEvent(BasicEvent *Event, uint64 e_time, bool set_addtime=true)
Definition EventProcessor.h:103
uint64 CalculateTime(uint64 t_offset) const
Definition EventProcessor.cpp:159
Definition Spell.h:862
Definition SpellInfo.h:317
uint32 SpellLevel
Definition SpellInfo.h:361
SpellInfo const * GetFirstRankSpell() const
Definition SpellInfo.cpp:2508
uint32 SpellIconID
Definition SpellInfo.h:381
SpellCastResult CheckTarget(Unit const *caster, WorldObject const *target, bool implicit=true) const
Definition SpellInfo.cpp:1754
bool CheckEffectTarget(Unit const *target, uint32 eff) const
Definition Spell.cpp:7968
bool IsAlive() const
Definition Unit.h:1710
SpellMissInfo SpellHitResult(Unit *victim, SpellInfo const *spell, bool canReflect=false)
Definition Unit.cpp:3504
virtual bool IsImmunedToSpellEffect(SpellInfo const *spellInfo, uint32 index) const
Definition Unit.cpp:13100
uint8 GetLevel() const
Definition Unit.h:1028
EventProcessor m_Events
Definition Object.h:731
Definition CreatureData.h:186
uint32 family
Definition CreatureData.h:217
float GetPositionZ() const
Definition Position.h:123
float GetPositionX() const
Definition Position.h:121
float GetPositionY() const
Definition Position.h:122
Definition Spell.h:264
bool processed
Definition Spell.h:270
int32 damage
Definition Spell.h:274
SpellMissInfo missCondition
Definition Spell.h:267
bool scaleAura
Definition Spell.h:273
bool crit
Definition Spell.h:272
uint64 timeDelay
Definition Spell.h:266
ObjectGuid targetGUID
Definition Spell.h:265
SpellMissInfo reflectResult
Definition Spell.h:268
bool alive
Definition Spell.h:271
uint8 effectMask
Definition Spell.h:269

References EventProcessor::AddEvent(), TargetInfo::alive, EventProcessor::CalculateTime(), cancel(), CheckEffectTarget(), SpellInfo::CheckTarget(), CREATURE_FAMILY_SUCCUBUS, TargetInfo::crit, TargetInfo::damage, TargetInfo::effectMask, SpellInfo::Effects, CreatureTemplate::family, WorldObject::GetDistance(), Object::GetEntry(), SpellInfo::GetFirstRankSpell(), Object::GetGUID(), Unit::GetLevel(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::IsAlive(), Unit::IsImmunedToSpellEffect(), Unit::IsPet(), m_auraScaleMask, m_canReflect, m_caster, m_delayMoment, WorldObject::m_Events, m_originalCaster, m_skipCheck, m_spellFlags, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, TargetInfo::missCondition, TargetInfo::processed, TargetInfo::reflectResult, TargetInfo::scaleAura, sObjectMgr, SpellInfo::Speed, SPELL_CAST_OK, SPELL_FLAG_REFLECTED, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE, SPELL_MISS_NONE, SPELL_MISS_PARRY, SPELL_MISS_REFLECT, Unit::SpellHitResult(), SpellInfo::SpellIconID, SpellInfo::SpellLevel, sScriptMgr, TargetInfo::targetGUID, and TargetInfo::timeDelay.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ CalculateDelayMomentForDst()

uint64 Spell::CalculateDelayMomentForDst ( ) const
900{
901 if (m_targets.HasDst())
902 {
903 if (m_targets.HasTraj())
904 {
905 float speed = m_targets.GetSpeedXY();
906 if (speed > 0.0f)
907 return (uint64)std::floor(m_targets.GetDist2d() / speed * 1000.0f);
908 }
909 else if (m_spellInfo->Speed > 0.0f)
910 {
911 // We should not subtract caster size from dist calculation (fixes execution time desync with animation on client, eg. Malleable Goo cast by PP)
912 float dist = m_caster->GetExactDist(*m_targets.GetDstPos());
913 return (uint64)std::floor(dist / m_spellInfo->Speed * 1000.0f);
914 }
915 }
916
917 return 0;
918}
bool HasTraj() const
Definition Spell.h:175
bool HasDst() const
Definition Spell.h:174
float GetSpeedXY() const
Definition Spell.h:183
float GetDist2d() const
Definition Spell.h:182
WorldLocation const * GetDstPos() const
Definition Spell.cpp:401
float GetExactDist(float x, float y, float z) const
Definition Position.h:182

References SpellCastTargets::GetDist2d(), SpellCastTargets::GetDstPos(), Position::GetExactDist(), SpellCastTargets::GetSpeedXY(), SpellCastTargets::HasDst(), SpellCastTargets::HasTraj(), m_caster, m_spellInfo, m_targets, and SpellInfo::Speed.

Referenced by RecalculateDelayMomentForDst(), and SelectSpellTargets().

◆ CalculateJumpSpeeds()

void Spell::CalculateJumpSpeeds ( uint8  i,
float  dist,
float &  speedxy,
float &  speedz 
)
protected
1154{
1156 if (Creature* creature = m_caster->ToCreature())
1157 runSpeed *= creature->GetCreatureTemplate()->speed_run;
1158
1159 float multiplier = m_spellInfo->Effects[i].ValueMultiplier;
1160 if (multiplier <= 0.0f)
1161 multiplier = 1.0f;
1162
1163 speedXY = std::min(runSpeed * 3.0f * multiplier, std::max(28.0f, m_caster->GetSpeed(MOVE_RUN) * 4.0f));
1164
1165 float duration = dist / speedXY;
1166 float durationSqr = duration * duration;
1167 float minHeight = m_spellInfo->Effects[i].MiscValue ? m_spellInfo->Effects[i].MiscValue / 10.0f : 0.5f; // Lower bound is blizzlike
1168 float maxHeight = m_spellInfo->Effects[i].MiscValueB ? m_spellInfo->Effects[i].MiscValueB / 10.0f : 1000.0f; // Upper bound is unknown
1169 float height;
1170 if (durationSqr < minHeight * 8 / Movement::gravity)
1171 height = minHeight;
1172 else if (durationSqr > maxHeight * 8 / Movement::gravity)
1173 height = maxHeight;
1174 else
1175 height = Movement::gravity * durationSqr / 8;
1176
1177 speedZ = std::sqrt(2 * Movement::gravity * height);
1178}
@ MOVE_RUN
Definition UnitDefines.h:352
float baseMoveSpeed[MAX_MOVE_TYPE]
Definition Unit.cpp:75
float playerBaseMoveSpeed[MAX_MOVE_TYPE]
Definition Unit.cpp:88
float GetSpeed(UnitMoveType mtype) const
Definition Unit.cpp:14525
double gravity
Definition MovementUtil.cpp:24

References baseMoveSpeed, SpellInfo::Effects, Unit::GetSpeed(), Movement::gravity, Unit::IsControlledByPlayer(), m_caster, m_spellInfo, MOVE_RUN, playerBaseMoveSpeed, and Object::ToCreature().

Referenced by EffectJump(), and EffectJumpDest().

◆ CalculateSpellDamage()

int32 Spell::CalculateSpellDamage ( uint8  i,
Unit const *  target 
) const
inline
int32 CalculateSpellDamage(Unit const *target, SpellInfo const *spellProto, uint8 effect_index, int32 const *basePoints=nullptr) const
Definition Unit.cpp:14952
int32 EffectBasePoints[MAX_SPELL_EFFECTS]
Definition Spell.h:222

References Unit::CalculateSpellDamage(), SpellValue::EffectBasePoints, m_caster, m_spellInfo, and m_spellValue.

Referenced by CheckCast(), CheckEffectTarget(), EffectWeaponDmg(), and HandleEffects().

◆ CallScriptAfterCastHandlers()

void Spell::CallScriptAfterCastHandlers ( )
protected
8600{
8601 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8602 {
8603 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_CAST);
8604 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->AfterCast.end(), hookItr = (*scritr)->AfterCast.begin();
8605 for (; hookItr != hookItrEnd; ++hookItr)
8606 (*hookItr).Call(*scritr);
8607
8608 (*scritr)->_FinishScriptCall();
8609 }
8610}
@ SPELL_SCRIPT_HOOK_AFTER_CAST
Definition SpellScript.h:172

References m_loadedScripts, and SPELL_SCRIPT_HOOK_AFTER_CAST.

Referenced by _cast().

◆ CallScriptAfterHitHandlers()

void Spell::CallScriptAfterHitHandlers ( )
protected
8712{
8713 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8714 {
8715 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_HIT);
8716 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->AfterHit.end(), hookItr = (*scritr)->AfterHit.begin();
8717 for (; hookItr != hookItrEnd; ++hookItr)
8718 (*hookItr).Call(*scritr);
8719
8720 (*scritr)->_FinishScriptCall();
8721 }
8722}
@ SPELL_SCRIPT_HOOK_AFTER_HIT
Definition SpellScript.h:165

References m_loadedScripts, and SPELL_SCRIPT_HOOK_AFTER_HIT.

Referenced by DoAllEffectOnTarget(), DoAllEffectOnTarget(), and DoAllEffectOnTarget().

◆ CallScriptBeforeCastHandlers()

void Spell::CallScriptBeforeCastHandlers ( )
protected
8574{
8575 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8576 {
8577 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_CAST);
8578 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->BeforeCast.end(), hookItr = (*scritr)->BeforeCast.begin();
8579 for (; hookItr != hookItrEnd; ++hookItr)
8580 (*hookItr).Call(*scritr);
8581
8582 (*scritr)->_FinishScriptCall();
8583 }
8584}
@ SPELL_SCRIPT_HOOK_BEFORE_CAST
Definition SpellScript.h:170

References m_loadedScripts, and SPELL_SCRIPT_HOOK_BEFORE_CAST.

Referenced by _cast().

◆ CallScriptBeforeHitHandlers()

void Spell::CallScriptBeforeHitHandlers ( SpellMissInfo  missInfo)
protected
8686{
8687 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8688 {
8689 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_HIT);
8690 std::list<SpellScript::BeforeHitHandler>::iterator hookItrEnd = (*scritr)->BeforeHit.end(), hookItr = (*scritr)->BeforeHit.begin();
8691 for (; hookItr != hookItrEnd; ++hookItr)
8692 (*hookItr).Call(*scritr, missInfo);
8693
8694 (*scritr)->_FinishScriptCall();
8695 }
8696}
@ SPELL_SCRIPT_HOOK_BEFORE_HIT
Definition SpellScript.h:163

References m_loadedScripts, and SPELL_SCRIPT_HOOK_BEFORE_HIT.

Referenced by DoAllEffectOnTarget(), DoAllEffectOnTarget(), and DoAllEffectOnTarget().

◆ CallScriptCheckCastHandlers()

SpellCastResult Spell::CallScriptCheckCastHandlers ( )
protected
8613{
8615 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8616 {
8617 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_CHECK_CAST);
8618 std::list<SpellScript::CheckCastHandler>::iterator hookItrEnd = (*scritr)->OnCheckCast.end(), hookItr = (*scritr)->OnCheckCast.begin();
8619 for (; hookItr != hookItrEnd; ++hookItr)
8620 {
8621 SpellCastResult tempResult = (*hookItr).Call(*scritr);
8622 if (retVal == SPELL_CAST_OK)
8623 retVal = tempResult;
8624 }
8625
8626 (*scritr)->_FinishScriptCall();
8627 }
8628 return retVal;
8629}
@ SPELL_SCRIPT_HOOK_CHECK_CAST
Definition SpellScript.h:169

References m_loadedScripts, SPELL_CAST_OK, and SPELL_SCRIPT_HOOK_CHECK_CAST.

Referenced by CheckCast().

◆ CallScriptDestinationTargetSelectHandlers()

void Spell::CallScriptDestinationTargetSelectHandlers ( SpellDestination target,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8753{
8754 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8755 {
8756 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT);
8757 std::list<SpellScript::DestinationTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnDestinationTargetSelect.end(), hookItr = (*scritr)->OnDestinationTargetSelect.begin();
8758 for (; hookItr != hookItrEnd; ++hookItr)
8759 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8760 hookItr->Call(*scritr, target);
8761
8762 (*scritr)->_FinishScriptCall();
8763 }
8764}
@ SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT
Definition SpellScript.h:168

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT.

Referenced by SelectImplicitCasterDestTargets(), SelectImplicitDestDestTargets(), SelectImplicitTargetDestTargets(), and SelectImplicitTrajTargets().

◆ CallScriptEffectHandlers()

bool Spell::CallScriptEffectHandlers ( SpellEffIndex  effIndex,
SpellEffectHandleMode  mode 
)
protected
8638{
8639 // execute script effect handler hooks and check if effects was prevented
8640 bool preventDefault = false;
8641 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8642 {
8643 std::list<SpellScript::EffectHandler>::iterator effItr, effEndItr;
8644 SpellScriptHookType hookType;
8645 switch (mode)
8646 {
8648 effItr = (*scritr)->OnEffectLaunch.begin();
8649 effEndItr = (*scritr)->OnEffectLaunch.end();
8651 break;
8653 effItr = (*scritr)->OnEffectLaunchTarget.begin();
8654 effEndItr = (*scritr)->OnEffectLaunchTarget.end();
8656 break;
8658 effItr = (*scritr)->OnEffectHit.begin();
8659 effEndItr = (*scritr)->OnEffectHit.end();
8661 break;
8663 effItr = (*scritr)->OnEffectHitTarget.begin();
8664 effEndItr = (*scritr)->OnEffectHitTarget.end();
8666 break;
8667 default:
8668 ABORT();
8669 return false;
8670 }
8671 (*scritr)->_PrepareScriptCall(hookType);
8672 for (; effItr != effEndItr; ++effItr)
8673 // effect execution can be prevented
8674 if (!(*scritr)->_IsEffectPrevented(effIndex) && (*effItr).IsEffectAffected(m_spellInfo, effIndex))
8675 (*effItr).Call(*scritr, effIndex);
8676
8677 if (!preventDefault)
8678 preventDefault = (*scritr)->_IsDefaultEffectPrevented(effIndex);
8679
8680 (*scritr)->_FinishScriptCall();
8681 }
8682 return preventDefault;
8683}
#define ABORT
Definition Errors.h:76
SpellScriptHookType
Definition SpellScript.h:158
@ SPELL_SCRIPT_HOOK_EFFECT_HIT
Definition SpellScript.h:161
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH
Definition SpellScript.h:159
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET
Definition SpellScript.h:160
@ SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET
Definition SpellScript.h:162
@ SPELL_EFFECT_HANDLE_LAUNCH_TARGET
Definition Spell.h:244
@ SPELL_EFFECT_HANDLE_HIT_TARGET
Definition Spell.h:246

References ABORT, m_loadedScripts, m_spellInfo, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_SCRIPT_HOOK_EFFECT_HIT, SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET, SPELL_SCRIPT_HOOK_EFFECT_LAUNCH, and SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET.

Referenced by HandleEffects().

◆ CallScriptObjectAreaTargetSelectHandlers()

void Spell::CallScriptObjectAreaTargetSelectHandlers ( std::list< WorldObject * > &  targets,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8725{
8726 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8727 {
8728 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT);
8729 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectAreaTargetSelect.end(), hookItr = (*scritr)->OnObjectAreaTargetSelect.begin();
8730 for (; hookItr != hookItrEnd; ++hookItr)
8731 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8732 hookItr->Call(*scritr, targets);
8733
8734 (*scritr)->_FinishScriptCall();
8735 }
8736}
@ SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT
Definition SpellScript.h:166

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT.

Referenced by SelectImplicitAreaTargets(), SelectImplicitChainTargets(), and SelectImplicitConeTargets().

◆ CallScriptObjectTargetSelectHandlers()

void Spell::CallScriptObjectTargetSelectHandlers ( WorldObject *&  target,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8739{
8740 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8741 {
8742 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT);
8743 std::list<SpellScript::ObjectTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectTargetSelect.end(), hookItr = (*scritr)->OnObjectTargetSelect.begin();
8744 for (; hookItr != hookItrEnd; ++hookItr)
8745 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8746 hookItr->Call(*scritr, target);
8747
8748 (*scritr)->_FinishScriptCall();
8749 }
8750}
@ SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT
Definition SpellScript.h:167

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChannelTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ CallScriptOnCastHandlers()

void Spell::CallScriptOnCastHandlers ( )
protected
8587{
8588 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8589 {
8590 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_ON_CAST);
8591 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->OnCast.end(), hookItr = (*scritr)->OnCast.begin();
8592 for (; hookItr != hookItrEnd; ++hookItr)
8593 (*hookItr).Call(*scritr);
8594
8595 (*scritr)->_FinishScriptCall();
8596 }
8597}
@ SPELL_SCRIPT_HOOK_ON_CAST
Definition SpellScript.h:171

References m_loadedScripts, and SPELL_SCRIPT_HOOK_ON_CAST.

Referenced by _cast().

◆ CallScriptOnHitHandlers()

void Spell::CallScriptOnHitHandlers ( )
protected
8699{
8700 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8701 {
8702 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_HIT);
8703 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->OnHit.end(), hookItr = (*scritr)->OnHit.begin();
8704 for (; hookItr != hookItrEnd; ++hookItr)
8705 (*hookItr).Call(*scritr);
8706
8707 (*scritr)->_FinishScriptCall();
8708 }
8709}
@ SPELL_SCRIPT_HOOK_HIT
Definition SpellScript.h:164

References m_loadedScripts, and SPELL_SCRIPT_HOOK_HIT.

Referenced by DoAllEffectOnTarget(), DoAllEffectOnTarget(), and DoAllEffectOnTarget().

◆ CanAutoCast()

bool Spell::CanAutoCast ( Unit target)
7038{
7039 ObjectGuid targetguid = target->GetGUID();
7040
7041 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
7042 {
7044 {
7045 if (m_spellInfo->StackAmount <= 1)
7046 {
7047 if (target->HasAuraEffect(m_spellInfo->Id, j))
7048 return false;
7049 }
7050 else
7051 {
7052 if (AuraEffect* aureff = target->GetAuraEffect(m_spellInfo->Id, j))
7053 if (aureff->GetBase()->GetStackAmount() >= m_spellInfo->StackAmount)
7054 return false;
7055 }
7056 }
7057 else if (m_spellInfo->Effects[j].IsAreaAuraEffect())
7058 {
7059 if (target->HasAuraEffect(m_spellInfo->Id, j))
7060 return false;
7061 }
7062 }
7063
7064 SpellCastResult result = CheckPetCast(target);
7065
7066 if (result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
7067 {
7069 //check if among target units, our WANTED target is as well (->only self cast spells return false)
7070 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7071 if (ihit->targetGUID == targetguid)
7072 return true;
7073 }
7074 return false; //target invalid
7075}
@ SPELL_EFFECT_APPLY_AURA
Definition SharedDefines.h:795
@ SPELL_FAILED_UNIT_NOT_INFRONT
Definition SharedDefines.h:1094
Definition SpellAuraEffects.h:39
uint32 StackAmount
Definition SpellInfo.h:372
SpellCastResult CheckPetCast(Unit *target)
Definition Spell.cpp:6844
AuraEffect * GetAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid casterGUID=ObjectGuid::Empty) const
Definition Unit.cpp:5559
bool HasAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid caster=ObjectGuid::Empty) const
Definition Unit.cpp:5733

References CheckPetCast(), SpellInfo::Effects, Unit::GetAuraEffect(), Object::GetGUID(), Unit::HasAuraEffect(), SpellInfo::Id, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, SelectSpellTargets(), SPELL_CAST_OK, SPELL_EFFECT_APPLY_AURA, SPELL_FAILED_UNIT_NOT_INFRONT, and SpellInfo::StackAmount.

Referenced by PetAI::UpdateAI().

◆ cancel()

void Spell::cancel ( bool  bySelf = false)
3728{
3730 return;
3731
3732 uint32 oldState = m_spellState;
3734
3735 m_autoRepeat = false;
3736 switch (oldState)
3737 {
3741
3742 if (m_caster->IsPlayer())
3743 {
3745 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3746 }
3747 [[fallthrough]];
3750 break;
3752 if (!bySelf)
3753 {
3754 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3755 if ((*ihit).missCondition == SPELL_MISS_NONE)
3756 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3757 unit->RemoveOwnedAura(m_spellInfo->Id, m_originalCasterGUID, 0, AURA_REMOVE_BY_CANCEL);
3758
3761
3764 }
3765
3767 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3768
3769 // spell is canceled-take mods and clear list
3770 if (Player* player = m_caster->GetSpellModOwner())
3771 player->RemoveSpellMods(this);
3772
3773 m_appliedMods.clear();
3774 break;
3775 default:
3776 break;
3777 }
3778
3780 if (m_selfContainer && *m_selfContainer == this)
3781 *m_selfContainer = nullptr;
3782
3783 // Do not remove current far sight object (already done in Spell::EffectAddFarsight) to prevent from reset viewpoint to player
3785 {
3787 }
3788
3789 if (m_spellInfo->IsChanneled()) // if not channeled then the object for the current cast wasn't summoned yet
3791
3792 //set state back so finish will be processed
3793 m_spellState = oldState;
3794
3795 sScriptMgr->OnSpellCastCancel(this, m_caster, m_spellInfo, bySelf);
3796
3797 finish(false);
3798}
@ SPELL_EFFECT_ADD_FARSIGHT
Definition SharedDefines.h:861
@ SPELL_FAILED_INTERRUPTED
Definition SharedDefines.h:1000
@ AURA_REMOVE_BY_CANCEL
Definition SpellAuraDefines.h:393
@ SPELL_STATE_PREPARING
Definition Spell.h:234
@ SPELL_STATE_CASTING
Definition Spell.h:235
bool NeedSendSpectatorData() const
Definition Player.cpp:15426
void SendChannelUpdate(uint32 time)
Definition Spell.cpp:5220
void CancelGlobalCooldown()
Definition Spell.cpp:8940
void SetReferencedFromCurrent(bool yes)
Definition Spell.h:583
UsedSpellMods m_appliedMods
Definition Spell.h:568
void RemoveGameObject(GameObject *gameObj, bool del)
Definition Unit.cpp:6293
bool RemoveDynObject(uint32 spellId)
Definition Unit.cpp:6237
Map * FindMap() const
Definition Object.h:622
void SendCommand_Spell(T *o, ObjectGuid targetGUID, const char *prefix, uint32 id, int32 casttime)
Definition ArenaSpectator.h:80

References AURA_REMOVE_BY_CANCEL, CancelGlobalCooldown(), WorldObject::FindMap(), finish(), Object::GetGUID(), Unit::GetSpellModOwner(), ObjectAccessor::GetUnit(), SpellInfo::HasEffect(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsCooldownStartedOnEvent(), Object::IsPlayer(), m_appliedMods, m_autoRepeat, m_caster, m_originalCasterGUID, m_selfContainer, m_spellInfo, m_spellState, m_UniqueTargetInfo, Player::NeedSendSpectatorData(), Unit::RemoveDynObject(), Unit::RemoveGameObject(), Player::RemoveSpellCooldown(), SendCastResult(), SendChannelUpdate(), ArenaSpectator::SendCommand_Spell(), SendInterrupted(), SetReferencedFromCurrent(), SPELL_EFFECT_ADD_FARSIGHT, SPELL_FAILED_INTERRUPTED, SPELL_MISS_NONE, SPELL_STATE_CASTING, SPELL_STATE_DELAYED, SPELL_STATE_FINISHED, SPELL_STATE_PREPARING, sScriptMgr, and Object::ToPlayer().

Referenced by _cast(), SpellEvent::Abort(), AddUnitTarget(), SpellScript::Cancel(), Unit::InterruptSpell(), update(), and SpellEvent::~SpellEvent().

◆ CancelGlobalCooldown()

void Spell::CancelGlobalCooldown ( )
protected
8941{
8943 return;
8944
8945 // Cancel global cooldown when interrupting current cast
8947 return;
8948
8949 // Only players or controlled units have global cooldown
8950 if (m_caster->GetCharmInfo())
8952 else if (m_caster->IsPlayer())
8954}
@ CURRENT_GENERIC_SPELL
Definition Unit.h:539
void CancelGlobalCooldown(SpellInfo const *spellInfo)
Definition CharmInfo.cpp:424
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition Player.h:1807
uint32 StartRecoveryTime
Definition SpellInfo.h:352
CharmInfo * GetCharmInfo()
Definition Unit.h:1210
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition Unit.h:1497
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition CharmInfo.h:160

References GlobalCooldownMgr::CancelGlobalCooldown(), CURRENT_GENERIC_SPELL, Unit::GetCharmInfo(), Unit::GetCurrentSpell(), Player::GetGlobalCooldownMgr(), CharmInfo::GetGlobalCooldownMgr(), Object::IsPlayer(), m_caster, m_spellInfo, SpellInfo::StartRecoveryTime, and Object::ToPlayer().

Referenced by cancel().

◆ CanExecuteTriggersOnHit()

bool Spell::CanExecuteTriggersOnHit ( uint8  effMask,
SpellInfo const *  triggeredByAura = nullptr 
) const
protected
8790{
8791 // Relentless strikes, proc only from first effect
8792 if (triggeredByAura && triggeredByAura->SpellIconID == 559)
8793 return effMask & (1 << EFFECT_0);
8794
8795 bool only_on_caster = (triggeredByAura && triggeredByAura->HasAttribute(SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET));
8796 // If triggeredByAura has SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET then it can only proc on a casted spell with TARGET_UNIT_CASTER
8797 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8798 {
8799 if ((effMask & (1 << i)) && (!only_on_caster || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_CASTER)))
8800 return true;
8801 }
8802 return effMask;
8803}
@ EFFECT_0
Definition SharedDefines.h:31
@ TARGET_UNIT_CASTER
Definition SharedDefines.h:1421
@ SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET
Definition SharedDefines.h:542

References EFFECT_0, SpellInfo::Effects, SpellInfo::HasAttribute(), m_spellInfo, MAX_SPELL_EFFECTS, SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET, SpellInfo::SpellIconID, and TARGET_UNIT_CASTER.

Referenced by DoAllEffectOnTarget(), and DoTriggersOnSpellHit().

◆ CanOpenLock()

SpellCastResult Spell::CanOpenLock ( uint32  effIndex,
uint32  lockid,
SkillType skillid,
int32 reqSkillValue,
int32 skillValue 
)
protected
8405{
8406 if (!lockId) // possible case for GO and maybe for items.
8407 return SPELL_CAST_OK;
8408
8409 // Get LockInfo
8410 LockEntry const* lockInfo = sLockStore.LookupEntry(lockId);
8411
8412 if (!lockInfo)
8414
8415 bool reqKey = false; // some locks not have reqs
8416
8417 for (int j = 0; j < MAX_LOCK_CASE; ++j)
8418 {
8419 switch (lockInfo->Type[j])
8420 {
8421 // check key item (many fit cases can be)
8422 case LOCK_KEY_ITEM:
8423 if (lockInfo->Index[j] && m_CastItem && m_CastItem->GetEntry() == lockInfo->Index[j])
8424 return SPELL_CAST_OK;
8425 reqKey = true;
8426 break;
8427 // check key skill (only single first fit case can be)
8428 case LOCK_KEY_SKILL:
8429 {
8430 reqKey = true;
8431
8432 // wrong locktype, skip
8433 if (uint32(m_spellInfo->Effects[effIndex].MiscValue) != lockInfo->Index[j])
8434 continue;
8435
8436 skillId = SkillByLockType(LockType(lockInfo->Index[j]));
8437
8438 if (skillId != SKILL_NONE)
8439 {
8440 reqSkillValue = lockInfo->Skill[j];
8441
8442 // castitem check: rogue using skeleton keys. the skill values should not be added in this case.
8443 skillValue = m_CastItem || !m_caster->IsPlayer() ?
8444 0 : m_caster->ToPlayer()->GetSkillValue(skillId);
8445
8446 // skill bonus provided by casting spell (mostly item spells)
8447 // add the effect base points modifier from the spell casted (cheat lock / skeleton key etc.)
8448 if ((m_spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET || m_spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET)
8450 {
8451 skillValue += m_spellInfo->Effects[effIndex].CalcValue();
8452 }
8453
8454 if (skillValue < reqSkillValue)
8456 }
8457
8458 return SPELL_CAST_OK;
8459 }
8460 case LOCK_KEY_SPELL:
8461 {
8462 if (m_spellInfo->Id == lockInfo->Index[j])
8463 {
8464 return SPELL_CAST_OK;
8465 }
8466 reqKey = true;
8467 break;
8468 }
8469 }
8470 }
8471
8472 if (reqKey)
8474
8475 return SPELL_CAST_OK;
8476}
DBCStorage< LockEntry > sLockStore(LockEntryfmt)
#define MAX_LOCK_CASE
Definition DBCStructure.h:1306
@ TARGET_GAMEOBJECT_ITEM_TARGET
Definition SharedDefines.h:1441
LockType
Definition SharedDefines.h:2602
@ LOCK_KEY_ITEM
Definition SharedDefines.h:2596
@ LOCK_KEY_SKILL
Definition SharedDefines.h:2597
@ LOCK_KEY_SPELL
Definition SharedDefines.h:2598
@ SPELL_FAILED_BAD_TARGETS
Definition SharedDefines.h:972
@ SPELL_FAILED_LOW_CASTLEVEL
Definition SharedDefines.h:1009
SkillType SkillByLockType(LockType locktype)
Definition SharedDefines.h:3270
@ SKILL_NONE
Definition SharedDefines.h:3114
@ SKILL_LOCKPICKING
Definition SharedDefines.h:3225
uint16 GetSkillValue(uint32 skill) const
Definition Player.cpp:5486
bool IsAbilityOfSkillType(uint32 skillType) const
Definition SpellInfo.cpp:1000
Definition DBCStructure.h:1309
uint32 Type[MAX_LOCK_CASE]
Definition DBCStructure.h:1311
uint32 Index[MAX_LOCK_CASE]
Definition DBCStructure.h:1312
uint32 Skill[MAX_LOCK_CASE]
Definition DBCStructure.h:1313

References SpellInfo::Effects, Object::GetEntry(), Player::GetSkillValue(), SpellInfo::Id, LockEntry::Index, SpellInfo::IsAbilityOfSkillType(), Object::IsPlayer(), LOCK_KEY_ITEM, LOCK_KEY_SKILL, LOCK_KEY_SPELL, m_caster, m_CastItem, m_spellInfo, MAX_LOCK_CASE, LockEntry::Skill, SKILL_LOCKPICKING, SKILL_NONE, SkillByLockType(), sLockStore, SPELL_CAST_OK, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_LOW_CASTLEVEL, TARGET_GAMEOBJECT_ITEM_TARGET, Object::ToPlayer(), and LockEntry::Type.

Referenced by CheckCast(), and EffectOpenLock().

◆ cast()

void Spell::cast ( bool  skipCheck = false)
3801{
3802 Player* modOwner = m_caster->GetSpellModOwner();
3803 Spell* lastMod = nullptr;
3804 if (modOwner)
3805 {
3806 lastMod = modOwner->m_spellModTakingSpell;
3807 if (lastMod)
3808 modOwner->SetSpellModTakingSpell(lastMod, false);
3809 }
3810
3811 _cast(skipCheck);
3812
3813 if (lastMod)
3814 modOwner->SetSpellModTakingSpell(lastMod, true);
3815}
Spell * m_spellModTakingSpell
Definition Player.h:2562
Definition Spell.h:294
void _cast(bool skipCheck)
Definition Spell.cpp:3817

References _cast(), Unit::GetSpellModOwner(), m_caster, Player::m_spellModTakingSpell, and Player::SetSpellModTakingSpell().

Referenced by Unit::AttackerStateUpdate(), prepare(), and update().

◆ CheckCast()

SpellCastResult Spell::CheckCast ( bool  strict)
Todo:
: determine if there is some flag to enable/disable the check
5684{
5685 // check death state
5688
5689 // Spectator check
5690 if (m_caster->IsPlayer())
5691 if (((Player const*)m_caster)->IsSpectator() && m_spellInfo->Id != SPECTATOR_SPELL_BINDSIGHT)
5692 return SPELL_FAILED_NOT_HERE;
5693
5695
5696 sScriptMgr->OnSpellCheckCast(this, strict, res);
5697
5698 if (res != SPELL_CAST_OK)
5699 return res;
5700
5701 // check cooldowns to prevent cheating
5703 {
5704 if (m_caster->IsPlayer())
5705 {
5706 //can cast triggered (by aura only?) spells while have this flag
5709
5711 {
5714 else
5716 }
5717
5718 // check if we are using a potion in combat for the 2nd+ time. Cooldown is added only after caster gets out of combat
5721 }
5724 }
5725
5727 {
5730 }
5731
5732 // Check global cooldown
5735
5736 // only triggered spells can be processed an ended battleground
5737 if (!IsTriggered() && m_caster->IsPlayer())
5739 if (bg->GetStatus() == STATUS_WAIT_LEAVE)
5741
5742 if (m_caster->IsPlayer() /*&& VMAP::VMapFactory::createOrGetVMapMgr()->isLineOfSightCalcEnabled()*/) // pussywizard: optimization (commented)
5743 {
5745 !m_caster->IsOutdoors())
5747
5751 }
5752
5753 // only check at first call, Stealth auras are already removed at second call
5754 // for now, ignore triggered spells
5756 {
5757 bool checkForm = true;
5758 // Ignore form req aura
5760 for (Unit::AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
5761 {
5762 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
5763 continue;
5764 checkForm = false;
5765 break;
5766 }
5767 if (checkForm)
5768 {
5769 // Cannot be used in this stance/form
5771 if (shapeError != SPELL_CAST_OK)
5772 return shapeError;
5773
5776 }
5777 }
5778
5780 for (Unit::AuraEffectList::const_iterator blockItr = blockSpells.begin(); blockItr != blockSpells.end(); ++blockItr)
5781 if (uint32((*blockItr)->GetMiscValue()) == m_spellInfo->SpellFamilyName)
5783
5784 bool reqCombat = true;
5786 for (Unit::AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j)
5787 {
5788 if ((*j)->IsAffectedOnSpell(m_spellInfo))
5789 {
5790 m_needComboPoints = false;
5791 if ((*j)->GetMiscValue() == 1)
5792 {
5793 reqCombat = false;
5794 break;
5795 }
5796 }
5797 }
5798
5799 // caster state requirements
5800 // not for triggered spells (needed by execute)
5802 {
5807
5808 // Note: spell 62473 requres CasterAuraSpell = triggering spell
5813
5814 if (reqCombat && m_caster->IsInCombat() && !m_spellInfo->CanBeUsedInCombat())
5816 }
5817
5818 // Xinef: exploit protection
5820 {
5821 if (m_caster->IsPlayer() && m_caster->GetMap()->IsDungeon())
5822 if (InstanceScript* instanceScript = m_caster->GetInstanceScript())
5823 if (instanceScript->IsEncounterInProgress())
5824 {
5825 if (Group* group = m_caster->ToPlayer()->GetGroup())
5826 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
5827 if (Player* member = itr->GetSource())
5828 if (member->IsInMap(m_caster))
5829 if (Unit* victim = member->GetVictim())
5830 if (victim->IsInCombat() && m_caster->GetDistance(victim) < m_caster->GetVisibilityRange())
5831 {
5832 m_caster->CombatStart(victim);
5833 victim->AddThreat(m_caster, 1.0f);
5834 break;
5835 }
5837 }
5838 }
5839
5840 // cancel autorepeat spells if cast start when moving
5841 // (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
5842 if (m_caster->IsPlayer() && m_caster->ToPlayer()->isMoving() && !IsTriggered())
5843 {
5844 // skip stuck spell to allow use it in falling case and apply spell limitations at movement
5847 return SPELL_FAILED_MOVING;
5848 }
5849
5850 Vehicle* vehicle = m_caster->GetVehicle();
5852 {
5853 uint16 checkMask = 0;
5854 for (uint8 effIndex = EFFECT_0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
5855 {
5856 SpellEffectInfo const* effInfo = &m_spellInfo->Effects[effIndex];
5858 {
5859 SpellShapeshiftFormEntry const* shapeShiftEntry = sSpellShapeshiftFormStore.LookupEntry(effInfo->MiscValue);
5860 if (shapeShiftEntry && (shapeShiftEntry->flags1 & SHAPESHIFT_FLAG_STANCE) == 0)
5861 checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
5862 break;
5863 }
5864 }
5865
5868
5869 if (!checkMask)
5870 checkMask = VEHICLE_SEAT_FLAG_CAN_ATTACK;
5871
5872 // All creatures should be able to cast as passengers freely, restriction and attribute are only for players
5873 VehicleSeatEntry const* vehicleSeat = vehicle->GetSeatForPassenger(m_caster);
5875 && (vehicleSeat->m_flags & checkMask) != checkMask && m_caster->IsPlayer())
5877 }
5878
5879 // check spell cast conditions from database
5880 {
5883 ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL, m_spellInfo->Id);
5884 if (!conditions.empty() && !sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
5885 {
5886 // mLastFailedCondition can be nullptr if there was an error processing the condition in Condition::Meets (i.e. wrong data for ConditionTarget or others)
5887 if (condInfo.mLastFailedCondition && condInfo.mLastFailedCondition->ErrorType)
5888 {
5892 }
5893 if (!condInfo.mLastFailedCondition || !condInfo.mLastFailedCondition->ConditionTarget)
5896 }
5897 }
5898
5899 // Don't check explicit target for passive spells (workaround) (check should be skipped only for learn case)
5900 // those spells may have incorrect target entries or not filled at all (for example 15332)
5901 // such spells when learned are not targeting anyone using targeting system, they should apply directly to caster instead
5902 // also, such casts shouldn't be sent to client
5903 // Xinef: do not check explicit casts for self cast of triggered spells (eg. reflect case)
5905 {
5906 // Check explicit target for m_originalCaster - todo: get rid of such workarounds
5907 // Xinef: do not check explicit target for triggered spell casted on self with targetflag enemy
5909 {
5911 if (castResult != SPELL_CAST_OK)
5912 return castResult;
5913 }
5914 }
5915
5916 if (Unit* target = m_targets.GetUnitTarget())
5917 {
5918 SpellCastResult castResult = m_spellInfo->CheckTarget(m_caster, target, false);
5919 if (castResult != SPELL_CAST_OK)
5920 return castResult;
5921
5922 if (target != m_caster)
5923 {
5924 // Must be behind the target
5925 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET) && target->HasInArc(static_cast<float>(M_PI), m_caster))
5927
5928 // Target must be facing you
5929 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER) && !target->HasInArc(static_cast<float>(M_PI), m_caster))
5931
5934 {
5935 bool castedByGameobject = false;
5936 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5938 {
5939 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5940 }
5941 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5942 {
5943 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5944 {
5945 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5946 }
5947 }
5948
5949 if (castedByGameobject)
5950 {
5951 // If spell casted by gameobject then ignore M2 models
5952 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5953 }
5954
5956 {
5958 }
5959 }
5960 }
5961 }
5962
5963 // Check for line of sight for spells with dest
5964 if (m_targets.HasDst())
5965 {
5966 float x, y, z;
5967 m_targets.GetDstPos()->GetPosition(x, y, z);
5968
5971 {
5972 bool castedByGameobject = false;
5973 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5975 {
5976 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5977 }
5978 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5979 {
5980 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5981 {
5982 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5983 }
5984 }
5985
5986 if (castedByGameobject)
5987 {
5988 // If spell casted by gameobject then ignore M2 models
5989 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5990 }
5991
5993 {
5995 }
5996 }
5997 }
5998
5999 // check pet presence
6000 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
6001 {
6002 if (m_spellInfo->Effects[j].TargetA.GetTarget() == TARGET_UNIT_PET)
6003 {
6005 {
6006 if (m_triggeredByAuraSpell.spellInfo) // not report pet not existence for triggered spells
6008 else
6009 return SPELL_FAILED_NO_PET;
6010 }
6011 break;
6012 }
6013 }
6014 // Spell casted only on battleground
6016 if (!m_caster->ToPlayer()->InBattleground())
6018
6019 // do not allow spells to be cast in arenas
6020 // - with greater than 10 min CD without SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS flag
6021 // - with SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND flag
6024 if (MapEntry const* mapEntry = sMapStore.LookupEntry(m_caster->GetMapId()))
6025 if (mapEntry->IsBattleArena())
6027
6028 // zone check
6030 {
6031 uint32 zone, area;
6032 m_caster->GetZoneAndAreaId(zone, area);
6033
6035 m_caster->IsPlayer() ? m_caster->ToPlayer() : nullptr);
6036 if (locRes != SPELL_CAST_OK)
6037 return locRes;
6038 }
6039
6040 // not let players cast spells at mount (and let do it to creatures)
6043 {
6044 if (m_caster->IsInFlight())
6046 else
6048 }
6049
6050 SpellCastResult castResult = SPELL_CAST_OK;
6051
6052 // always (except passive spells) check items (focus object can be required for any type casts)
6053 if (!m_spellInfo->IsPassive())
6054 {
6055 // spell focus needs to be checked not only for players! there are vehicle spells that require spell focus
6056 castResult = CheckSpellFocus();
6057 if (castResult != SPELL_CAST_OK)
6058 return castResult;
6059
6060 castResult = CheckItems();
6061 if (castResult != SPELL_CAST_OK)
6062 return castResult;
6063 }
6064
6065 // Triggered spells also have range check
6067 castResult = CheckRange(strict);
6068 if (castResult != SPELL_CAST_OK)
6069 return castResult;
6070
6072 {
6073 castResult = CheckPower();
6074 if (castResult != SPELL_CAST_OK)
6075 return castResult;
6076 }
6077
6079 {
6080 return SPELL_CAST_OK;
6081 }
6082
6083 // xinef: do not skip triggered spells if they posses prevention type (eg. Bladestorm vs Hand of Protection)
6085 {
6087 if (castResult != SPELL_CAST_OK)
6088 return castResult;
6089
6090 // xinef: Enraged Regeneration: While this is active, the warrior is blocked from using abilities that trigger being enraged (which would do nothing and waste the cooldowns).
6092 {
6094 for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
6095 if (itr->type == m_spellInfo->Mechanic)
6097 }
6098 }
6099
6100 // script hook
6101 castResult = CallScriptCheckCastHandlers();
6102 if (castResult != SPELL_CAST_OK)
6103 return castResult;
6104
6105 bool hasDispellableAura = false;
6106 bool hasNonDispelEffect = false;
6107 uint32 dispelMask = 0;
6108 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6109 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_DISPEL)
6110 {
6112 {
6113 hasDispellableAura = true;
6114 break;
6115 }
6116
6117 dispelMask |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6118 }
6119 else if (m_spellInfo->Effects[i].IsEffect())
6120 {
6121 hasNonDispelEffect = true;
6122 break;
6123 }
6124
6125 if (!hasNonDispelEffect && !hasDispellableAura && dispelMask && !IsTriggered())
6126 {
6127 if (Unit* target = m_targets.GetUnitTarget())
6128 {
6129 // Xinef: do not allow to cast on hostile targets in sanctuary
6130 if (!m_caster->IsFriendlyTo(target))
6131 {
6132 if (m_caster->IsInSanctuary() || target->IsInSanctuary())
6133 {
6134 // Xinef: fix for duels
6135 Player* player = m_caster->ToPlayer();
6136 if (!player || !player->duel || target != player->duel->Opponent)
6138 }
6139 }
6140
6141 DispelChargesList dispelList;
6142 target->GetDispellableAuraList(m_caster, dispelMask, dispelList, m_spellInfo);
6143
6144 if (dispelList.empty())
6146 }
6147 }
6148
6149 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6150 {
6151 // for effects of spells that have only one target
6152 switch (m_spellInfo->Effects[i].Effect)
6153 {
6155 {
6156 if (!m_caster->IsPlayer())
6158
6159 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_PET)
6160 break;
6161
6162 Pet* pet = m_caster->ToPlayer()->GetPet();
6163
6164 if (!pet)
6165 return SPELL_FAILED_NO_PET;
6166
6167 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6168
6169 if (!learn_spellproto)
6171
6172 if (m_spellInfo->SpellLevel > pet->GetLevel())
6173 return SPELL_FAILED_LOWLEVEL;
6174
6175 break;
6176 }
6178 {
6179 // check target only for unit target case
6181 {
6182 if (!m_caster->IsPlayer())
6184
6185 Pet* pet = unitTarget->ToPet();
6186 if (!pet || pet->GetOwner() != m_caster)
6188
6189 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6190
6191 if (!learn_spellproto)
6193
6194 if (m_spellInfo->SpellLevel > pet->GetLevel())
6195 return SPELL_FAILED_LOWLEVEL;
6196 }
6197 break;
6198 }
6200 {
6201 uint32 glyphId = m_spellInfo->Effects[i].MiscValue;
6202 if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyphId))
6203 if (m_caster->HasAura(gp->SpellId))
6205 break;
6206 }
6208 {
6209 if (!m_caster->IsPlayer())
6211
6212 Item* foodItem = m_targets.GetItemTarget();
6213 if (!foodItem)
6215
6216 Pet* pet = m_caster->ToPlayer()->GetPet();
6217
6218 if (!pet)
6219 return SPELL_FAILED_NO_PET;
6220
6221 if (!pet->HaveInDiet(foodItem->GetTemplate()))
6223
6224 if (!pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel))
6226
6227 if (m_caster->IsInCombat() || pet->IsInCombat())
6229
6230 break;
6231 }
6234 {
6235 // Can be area effect, Check only for players and not check if target - caster (spell can have multiply drain/burn effects)
6236 if (m_caster->IsPlayer())
6237 if (Unit* target = m_targets.GetUnitTarget())
6238 if (target != m_caster && !target->HasActivePowerType(Powers(m_spellInfo->Effects[i].MiscValue)))
6240 break;
6241 }
6243 {
6245 {
6247 }
6248
6250 {
6251 // Warbringer - can't be handled in proc system - should be done before checkcast root check and charge effect process
6252 if (strict && m_caster->IsScriptOverriden(m_spellInfo, 6953))
6254 }
6256 {
6257 // Exception for Master's Call
6258 if (m_spellInfo->Id != 54216)
6259 {
6260 return SPELL_FAILED_ROOTED;
6261 }
6262 }
6263 if (m_caster->IsPlayer())
6264 if (Unit* target = m_targets.GetUnitTarget())
6265 if (!target->IsAlive())
6267 // Xinef: Pass only explicit unit target spells
6268 // pussywizard:
6269 if (sDisableMgr->IsPathfindingEnabled(m_caster->FindMap()) && m_spellInfo->NeedsExplicitUnitTarget())
6270 {
6271 Unit* target = m_targets.GetUnitTarget();
6272 if (!target)
6274
6275 // first we must check to see if the target is in LoS. A path can usually be built but LoS matters for charge spells
6276 if (!target->IsWithinLOSInMap(m_caster)) //Do full LoS/Path check. Don't exclude m2
6278
6279 float objSize = target->GetCombatReach();
6280 float range = m_spellInfo->GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict
6281
6282 m_preGeneratedPath = std::make_unique<PathGenerator>(m_caster);
6283 m_preGeneratedPath->SetPathLengthLimit(range);
6284
6285 // first try with raycast, if it fails fall back to normal path
6286 bool result = m_preGeneratedPath->CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), false);
6287 if (m_preGeneratedPath->GetPathType() & PATHFIND_SHORT)
6288 return SPELL_FAILED_NOPATH;
6289 else if (!result || m_preGeneratedPath->GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE))
6290 return SPELL_FAILED_NOPATH;
6291 else if (m_preGeneratedPath->IsInvalidDestinationZ(target)) // Check position z, if not in a straight line
6292 return SPELL_FAILED_NOPATH;
6293
6294 m_preGeneratedPath->ShortenPathUntilDist(G3D::Vector3(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()), objSize); // move back
6295 }
6296 if (Player* player = m_caster->ToPlayer())
6297 player->SetCanTeleport(true);
6298 break;
6299 }
6301 {
6304
6307
6308 Creature* creature = m_targets.GetUnitTarget()->ToCreature();
6309 if (!creature->IsCritter() && !creature->loot.isLooted())
6311
6312 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
6313
6314 int32 skillValue = m_caster->ToPlayer()->GetSkillValue(skill);
6315 int32 TargetLevel = m_targets.GetUnitTarget()->GetLevel();
6316 int32 ReqValue = (skillValue < 100 ? (TargetLevel - 10) * 10 : TargetLevel * 5);
6317 if (ReqValue > skillValue)
6319
6320 break;
6321 }
6323 {
6324 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_TARGET &&
6325 m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_ITEM_TARGET)
6326 break;
6327
6328 if (!m_caster->IsPlayer() // only players can open locks, gather etc.
6329 // we need a go target in case of TARGET_GAMEOBJECT_TARGET
6330 || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget()))
6332
6333 Item* pTempItem = nullptr;
6335 {
6336 if (TradeData* pTrade = m_caster->ToPlayer()->GetTradeData())
6337 pTempItem = pTrade->GetTraderData()->GetItem(TradeSlots(m_targets.GetItemTargetGUID().GetRawValue()));
6338 }
6341
6342 // we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM_TARGET
6343 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET &&
6345 (!pTempItem || !pTempItem->GetTemplate()->LockID || !pTempItem->IsLocked()))
6347
6348 // We must also ensure the gameobject we are opening is still closed by the time the spell finishes.
6349 if (GameObject* go = m_targets.GetGOTarget())
6350 {
6351 if (go->GetGoType() == GAMEOBJECT_TYPE_DOOR && go->GetGoState() != GO_STATE_READY)
6352 {
6354 }
6355 }
6356 if (m_spellInfo->Id != 1842 || (m_targets.GetGOTarget() &&
6358 {
6359 if (m_targets.GetGOTarget() && m_targets.GetGOTarget()->GetEntry() == 179697)
6360 {
6361 if (!m_caster->ToPlayer()->CanUseBattlegroundObject(nullptr))
6363 }
6364 else if (m_caster->ToPlayer()->InBattleground() && // In Battleground players can use only flags and banners, or Gurubashi chest
6367 }
6368
6369 // get the lock entry
6370 uint32 lockId = 0;
6371 if (GameObject* go = m_targets.GetGOTarget())
6372 {
6373 lockId = go->GetGOInfo()->GetLockId();
6374 if (!lockId)
6376 }
6377 else if (Item* itm = m_targets.GetItemTarget())
6378 lockId = itm->GetTemplate()->LockID;
6379
6380 SkillType skillId = SKILL_NONE;
6381 int32 reqSkillValue = 0;
6382 int32 skillValue = 0;
6383
6384 // check lock compatibility
6385 SpellCastResult res = CanOpenLock(i, lockId, skillId, reqSkillValue, skillValue);
6386 if (res != SPELL_CAST_OK)
6387 return res;
6388
6389 // chance for fail at lockpicking attempt
6390 // second check prevent fail at rechecks
6391 // herbalism and mining cannot fail as of patch 3.1.0
6392 if (skillId != SKILL_NONE && skillId != SKILL_HERBALISM && skillId != SKILL_MINING && (!m_selfContainer || ((*m_selfContainer) != this)))
6393 {
6394 // chance for failure in orange lockpick
6395 if (skillId == SKILL_LOCKPICKING && reqSkillValue > irand(skillValue - 25, skillValue + 37))
6396 {
6398 }
6399 }
6400 break;
6401 }
6403 {
6404 Unit* unitCaster = m_caster->ToUnit();
6405 if (!unitCaster)
6406 {
6408 }
6409
6410 Creature* pet = unitCaster->GetGuardianPet();
6411 if (pet)
6412 {
6413 if (pet->IsAlive())
6414 {
6416 }
6417 }
6418 else if (Player* playerCaster = m_caster->ToPlayer())
6419 {
6420 PetStable& petStable = playerCaster->GetOrInitPetStable();
6421 if (!petStable.CurrentPet && petStable.UnslottedPets.empty())
6422 {
6423 return SPELL_FAILED_NO_PET;
6424 }
6425 }
6426
6427 break;
6428 }
6429 // This is generic summon effect
6431 {
6432 SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[i].MiscValueB);
6433 if (!SummonProperties || m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST))
6434 break;
6435 switch (SummonProperties->Category)
6436 {
6438 if (m_caster->GetPetGUID())
6440 [[fallthrough]];
6442 if (m_caster->GetCharmGUID())
6444 break;
6445 }
6446 break;
6447 }
6449 {
6451 {
6456 }
6457 break;
6458 }
6460 {
6461 Unit* unitCaster = m_caster->ToUnit();
6462 if (!unitCaster)
6464
6466 {
6467 if (m_caster->GetPetGUID())
6469 if (m_caster->GetCharmGUID())
6471 }
6472
6474 if (Pet* pet = m_caster->ToPlayer()->GetPet())
6475 pet->CastSpell(pet, 32752, true, nullptr, nullptr, pet->GetGUID()); //starting cast, trigger pet stun (cast by pet so it doesn't attack player)
6476
6477 Player* playerCaster = unitCaster->ToPlayer();
6478 if (playerCaster && playerCaster->GetPetStable())
6479 {
6480 std::pair<PetStable::PetInfo const*, PetSaveMode> info = Pet::GetLoadPetInfo(*playerCaster->GetPetStable(), m_spellInfo->Effects[i].MiscValue, 0, false);
6481 if (info.first)
6482 {
6483 if (info.first->Type == HUNTER_PET)
6484 {
6485 if (!info.first->Health)
6486 {
6487 playerCaster->SendTameFailure(PET_TAME_DEAD);
6489 }
6490
6491 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(info.first->CreatureId);
6492 if (!creatureInfo || !creatureInfo->IsTameable(playerCaster->CanTameExoticPets()))
6493 {
6494 // if problem in exotic pet
6495 if (creatureInfo && creatureInfo->IsTameable(true))
6497 else
6499
6501 }
6502 }
6503 }
6504 else if (!m_spellInfo->Effects[i].MiscValue) // when miscvalue is present it is allowed to create new pets
6505 {
6508 }
6509 }
6510 break;
6511 }
6513 {
6514 if (!m_caster->IsPlayer())
6516 if (!m_caster->GetTarget())
6518
6520 if (!target || (!target->IsInSameRaidWith(m_caster->ToPlayer()) && m_spellInfo->Id != 48955)) // refer-a-friend spell
6522
6523 // Xinef: Implement summon pending error
6524 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6526
6527 // check if our map is dungeon
6528 MapEntry const* map = sMapStore.LookupEntry(m_caster->GetMapId());
6529 if (map->IsDungeon())
6530 {
6531 uint32 mapId = m_caster->GetMap()->GetId();
6532 Difficulty difficulty = m_caster->GetMap()->GetDifficulty();
6533 /*if (map->IsRaid())
6534 if (InstancePlayerBind* targetBind = target->GetBoundInstance(mapId, difficulty))
6535 if (targetBind->perm && targetBind != m_caster->ToPlayer()->GetBoundInstance(mapId, difficulty))
6536 return SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE;*/
6537
6538 InstanceTemplate const* instance = sObjectMgr->GetInstanceTemplate(mapId);
6539 if (!instance)
6541 if (!target->Satisfy(sObjectMgr->GetAccessRequirement(mapId, difficulty), mapId))
6543 }
6544 break;
6545 }
6546 // RETURN HERE
6548 {
6549 if (!m_caster->IsPlayer())
6551
6552 Player* playerCaster = m_caster->ToPlayer();
6553 //
6554 if (!(playerCaster->GetTarget()))
6556
6558
6559 if (!target ||
6560 !(target->GetSession()->GetRecruiterId() == playerCaster->GetSession()->GetAccountId() || target->GetSession()->GetAccountId() == playerCaster->GetSession()->GetRecruiterId()))
6562
6563 // Xinef: Implement summon pending error
6564 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6566
6567 break;
6568 }
6569 case SPELL_EFFECT_LEAP:
6571 {
6572 //Do not allow to cast it before BG starts.
6573 if (m_caster->IsPlayer())
6574 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6575 if (bg->GetStatus() != STATUS_IN_PROGRESS)
6577 break;
6578 }
6580 {
6583
6584 bool found = false;
6586 for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)
6587 {
6588 if (itr->second->GetBase()->IsPassive())
6589 continue;
6590
6591 if (!itr->second->IsPositive())
6592 continue;
6593
6594 found = true;
6595 break;
6596 }
6597
6598 if (!found)
6600
6601 break;
6602 }
6604 {
6606 {
6607 if (m_caster->IsPlayer())
6608 return SPELL_FAILED_ROOTED;
6609 else
6611 }
6612 break;
6613 }
6614 // xinef: do not allow to use leaps while rooted
6615 case SPELL_EFFECT_JUMP:
6617 {
6619 return SPELL_FAILED_ROOTED;
6620 break;
6621 }
6623 if (!sScriptMgr->CanSelectSpecTalent(this))
6625 // can't change during already started arena/battleground
6626 if (m_caster->IsPlayer())
6627 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6628 if (bg->GetStatus() == STATUS_IN_PROGRESS)
6630 break;
6631 default:
6632 break;
6633 }
6634 }
6635
6636 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6637 {
6638 switch (m_spellInfo->Effects[i].ApplyAuraName)
6639 {
6640 case SPELL_AURA_DUMMY:
6641 break;
6643 {
6644 if (!m_caster->IsPlayer())
6645 return SPELL_FAILED_NO_PET;
6646
6647 Pet* pet = m_caster->ToPlayer()->GetPet();
6648 if (!pet)
6649 return SPELL_FAILED_NO_PET;
6650
6651 if (pet->GetCharmerGUID())
6652 return SPELL_FAILED_CHARMED;
6653 break;
6654 }
6658 {
6659 if (m_caster->GetCharmerGUID())
6660 return SPELL_FAILED_CHARMED;
6661
6662 // Xinef: allow SPELL_AURA_MOD_POSSESS to posses target if caster has some pet
6664 {
6665 if (m_caster->GetPetGUID())
6667
6668 if (m_caster->GetCharmGUID())
6670 }
6671 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS)
6672 {
6673 if (m_caster->GetCharmGUID())
6675 }
6676
6677 if (Unit* target = m_targets.GetUnitTarget())
6678 {
6679 if (target->IsCreature() && target->ToCreature()->IsVehicle())
6681
6682 if (target->IsMounted())
6684
6685 if (target->GetCharmerGUID())
6686 return SPELL_FAILED_CHARMED;
6687
6688 if (target->GetOwnerGUID() && target->GetOwnerGUID().IsPlayer())
6690
6691 if (target->IsPet() && (!target->GetOwner() || target->GetOwner()->ToPlayer()))
6693
6694 int32 damage = CalculateSpellDamage(i, target);
6695 if (damage && int32(target->GetLevel()) > damage)
6697 }
6698
6699 break;
6700 }
6701 case SPELL_AURA_MOUNTED:
6702 {
6703 // Disallow casting flying mounts in water
6706
6707 // Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells
6708 bool allowMount = !m_caster->GetMap()->IsDungeon() || m_caster->GetMap()->IsBattlegroundOrArena();
6709 InstanceTemplate const* it = sObjectMgr->GetInstanceTemplate(m_caster->GetMapId());
6710 if (it)
6711 allowMount = it->AllowMount;
6712 if (m_caster->IsPlayer() && !allowMount && !m_spellInfo->AreaGroupId)
6714
6717
6718 // xinef: dont allow to cast mounts in specific transforms
6719 if (m_caster->getTransForm())
6720 if (SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(m_caster->getTransForm()))
6721 if (transformSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) &&
6722 !transformSpellInfo->HasAttribute(SpellAttr0(SPELL_ATTR0_ALLOW_WHILE_MOUNTED | SPELL_ATTR0_AURA_IS_DEBUFF)))
6724
6725 break;
6726 }
6728 {
6729 if (!m_targets.GetUnitTarget())
6731
6732 // can be casted at non-friendly unit or own pet/charm
6735
6736 break;
6737 }
6738 case SPELL_AURA_FLY:
6740 {
6741 // Xinef: added water check
6742 if (m_caster->IsInWater())
6744
6745 // not allow cast fly spells if not have req. skills (all spells is self target)
6746 // allow always ghost flight spells
6748 {
6749 Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(m_originalCaster->GetZoneId());
6750 if (AreaTableEntry const* pArea = sAreaTableStore.LookupEntry(m_originalCaster->GetAreaId()))
6751 if ((pArea->flags & AREA_FLAG_NO_FLY_ZONE) || (Bf && !Bf->CanFlyIn()))
6752 return SPELL_FAILED_NOT_HERE;
6753 }
6754 break;
6755 }
6757 {
6758 if (m_spellInfo->Effects[i].IsTargetingArea())
6759 break;
6760
6761 if (!m_caster->IsPlayer() || m_CastItem)
6762 break;
6763
6764 if (!m_targets.GetUnitTarget())
6766
6769
6770 break;
6771 }
6772 case SPELL_AURA_HOVER:
6773 {
6775 {
6777 }
6778 break;
6779 }
6781 {
6782 if (m_caster && m_caster->HasAura(23397)) // Nefarian Class Call (Warrior): Berserk -- Nefertum: I don't really like this but I didn't find another way.
6783 {
6785 }
6786 break;
6787 }
6788 default:
6789 break;
6790 }
6791 }
6792
6793 // check trade slot case (last, for allow catch any another cast problems)
6795 {
6796 if (m_CastItem)
6798
6799 if (!m_caster->IsPlayer())
6801
6802 TradeData* my_trade = m_caster->ToPlayer()->GetTradeData();
6803
6804 if (!my_trade)
6806
6808 if (slot != TRADE_SLOT_NONTRADED)
6810
6811 if (!IsTriggered())
6812 if (my_trade->GetSpell())
6814 }
6815
6816 // check if caster has at least 1 combo point on target for spells that require combo points
6818 {
6820 {
6822 {
6824 }
6825 }
6826 else
6827 {
6828 if (!m_caster->GetComboPoints())
6829 {
6831 }
6832 }
6833 }
6834
6835 // xinef: check relic cooldown
6839
6840 // all ok
6841 return SPELL_CAST_OK;
6842}
#define SPECTATOR_SPELL_BINDSIGHT
Definition ArenaSpectator.h:38
#define sBattlefieldMgr
Definition BattlefieldMgr.h:77
@ STATUS_WAIT_LEAVE
Definition Battleground.h:194
@ STATUS_IN_PROGRESS
Definition Battleground.h:193
constexpr auto IN_MILLISECONDS
Definition Common.h:53
constexpr auto MINUTE
Definition Common.h:47
#define sConditionMgr
Definition ConditionMgr.h:291
@ CONDITION_SOURCE_TYPE_SPELL
Definition ConditionMgr.h:141
std::list< Condition * > ConditionList
Definition ConditionMgr.h:238
@ VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL
Definition DBCEnums.h:456
@ VEHICLE_SEAT_FLAG_UNCONTROLLED
Definition DBCEnums.h:457
@ VEHICLE_SEAT_FLAG_CAN_ATTACK
Definition DBCEnums.h:458
Difficulty
Definition DBCEnums.h:266
@ AREA_FLAG_NO_FLY_ZONE
Definition DBCEnums.h:262
DBCStorage< SummonPropertiesEntry > sSummonPropertiesStore(SummonPropertiesfmt)
DBCStorage< SpellShapeshiftFormEntry > sSpellShapeshiftFormStore(SpellShapeshiftFormEntryfmt)
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
DBCStorage< GlyphPropertiesEntry > sGlyphPropertiesStore(GlyphPropertiesfmt)
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
std::uint16_t uint16
Definition Define.h:108
#define sDisableMgr
Definition DisableMgr.h:88
@ GO_STATE_READY
Definition GameObjectData.h:692
@ INVTYPE_RELIC
Definition ItemTemplate.h:284
LineOfSightChecks
Definition Map.h:101
@ LINEOFSIGHT_ALL_CHECKS
Definition Map.h:108
@ PATHFIND_NOPATH
Definition PathGenerator.h:50
@ PATHFIND_SHORT
Definition PathGenerator.h:52
@ PATHFIND_INCOMPLETE
Definition PathGenerator.h:49
@ HUNTER_PET
Definition PetDefines.h:32
@ PLAYER_ALLOW_ONLY_ABILITY
Definition Player.h:492
int32 irand(int32 min, int32 max)
Definition Random.cpp:37
@ GAMEOBJECT_TYPE_TRAP
Definition SharedDefines.h:1577
@ GAMEOBJECT_TYPE_DOOR
Definition SharedDefines.h:1571
Powers
Definition SharedDefines.h:279
@ POWER_MANA
Definition SharedDefines.h:280
@ SPELL_ATTR7_DEBUG_SPELL
Definition SharedDefines.h:655
@ SPELL_EFFECT_LEAP
Definition SharedDefines.h:818
@ SPELL_EFFECT_POWER_BURN
Definition SharedDefines.h:851
@ SPELL_EFFECT_STUCK
Definition SharedDefines.h:873
@ SPELL_EFFECT_SUMMON_RAF_FRIEND
Definition SharedDefines.h:941
@ SPELL_EFFECT_APPLY_GLYPH
Definition SharedDefines.h:863
@ SPELL_EFFECT_FEED_PET
Definition SharedDefines.h:890
@ SPELL_EFFECT_SUMMON_PLAYER
Definition SharedDefines.h:874
@ SPELL_EFFECT_JUMP_DEST
Definition SharedDefines.h:831
@ SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER
Definition SharedDefines.h:832
@ SPELL_EFFECT_RESURRECT_PET
Definition SharedDefines.h:898
@ SPELL_EFFECT_LEAP_BACK
Definition SharedDefines.h:927
@ SPELL_EFFECT_SUMMON
Definition SharedDefines.h:817
@ SPELL_EFFECT_POWER_DRAIN
Definition SharedDefines.h:797
@ SPELL_EFFECT_RESURRECT
Definition SharedDefines.h:807
@ SPELL_EFFECT_CHARGE
Definition SharedDefines.h:885
@ SPELL_EFFECT_RESURRECT_NEW
Definition SharedDefines.h:902
@ SPELL_EFFECT_TALENT_SPEC_SELECT
Definition SharedDefines.h:951
@ SPELL_EFFECT_LEARN_SPELL
Definition SharedDefines.h:825
@ SPELL_EFFECT_JUMP
Definition SharedDefines.h:830
@ SPELL_EFFECT_SKINNING
Definition SharedDefines.h:884
@ SPELL_EFFECT_CREATE_TAMED_PET
Definition SharedDefines.h:942
@ SPELL_EFFECT_OPEN_LOCK
Definition SharedDefines.h:822
@ SPELL_EFFECT_STEAL_BENEFICIAL_BUFF
Definition SharedDefines.h:915
@ SPELL_EFFECT_LEARN_PET_SPELL
Definition SharedDefines.h:846
@ SPELL_PREVENTION_TYPE_NONE
Definition SharedDefines.h:1564
@ SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT
Definition SharedDefines.h:604
@ TARGET_UNIT_PET
Definition SharedDefines.h:1425
@ TARGET_GAMEOBJECT_TARGET
Definition SharedDefines.h:1438
@ SPELL_ATTR2_IGNORE_LINE_OF_SIGHT
Definition SharedDefines.h:469
@ SPELL_ATTR1_INITIATE_COMBAT
Definition SharedDefines.h:439
@ SPELL_ATTR3_ONLY_BATTLEGROUNDS
Definition SharedDefines.h:515
@ PET_TAME_NOPET_AVAILABLE
Definition SharedDefines.h:3949
@ PET_TAME_DEAD
Definition SharedDefines.h:3952
@ PET_TAME_CANT_CONTROL_EXOTIC
Definition SharedDefines.h:3954
@ CLASS_WARLOCK
Definition SharedDefines.h:149
@ IMMUNITY_MECHANIC
Definition SharedDefines.h:1410
@ SPELLFAMILY_WARRIOR
Definition SharedDefines.h:3798
SpellCustomErrors
Definition SharedDefines.h:1153
@ SPELL_CUSTOM_ERROR_GM_ONLY
Definition SharedDefines.h:1219
SpellAttr0
Definition SharedDefines.h:392
@ SPELL_ATTR0_ONLY_INDOORS
Definition SharedDefines.h:407
@ SPELL_ATTR0_AURA_IS_DEBUFF
Definition SharedDefines.h:419
@ SPELL_ATTR0_ONLY_OUTDOORS
Definition SharedDefines.h:408
@ SPELL_ATTR0_ALLOW_WHILE_MOUNTED
Definition SharedDefines.h:417
@ SPELL_ATTR0_PASSIVE
Definition SharedDefines.h:399
@ SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD
Definition SharedDefines.h:416
@ SPELL_ATTR0_ONLY_STEALTHED
Definition SharedDefines.h:410
AuraStateType
Definition SharedDefines.h:1299
DispelType
Definition SharedDefines.h:1382
@ SPELL_FAILED_TARGET_NOT_LOOTED
Definition SharedDefines.h:1081
@ SPELL_FAILED_NOT_INFRONT
Definition SharedDefines.h:1021
@ SPELL_FAILED_MOVING
Definition SharedDefines.h:1011
@ SPELL_FAILED_NOT_MOUNTED
Definition SharedDefines.h:1024
@ SPELL_FAILED_AFFECTING_COMBAT
Definition SharedDefines.h:961
@ SPELL_FAILED_CASTER_AURASTATE
Definition SharedDefines.h:982
@ SPELL_FAILED_NOTHING_TO_DISPEL
Definition SharedDefines.h:1046
@ SPELL_FAILED_NOT_KNOWN
Definition SharedDefines.h:1023
@ SPELL_FAILED_FOOD_LOWLEVEL
Definition SharedDefines.h:995
@ SPELL_FAILED_NOT_HERE
Definition SharedDefines.h:1020
@ SPELL_FAILED_ROOTED
Definition SharedDefines.h:1063
@ SPELL_FAILED_WRONG_PET_FOOD
Definition SharedDefines.h:1095
@ SPELL_FAILED_CUSTOM_ERROR
Definition SharedDefines.h:1132
@ SPELL_FAILED_SUMMON_PENDING
Definition SharedDefines.h:1143
@ SPELL_FAILED_DAMAGE_IMMUNE
Definition SharedDefines.h:1106
@ SPELL_FAILED_BAD_IMPLICIT_TARGETS
Definition SharedDefines.h:971
@ SPELL_FAILED_TRY_AGAIN
Definition SharedDefines.h:1092
@ SPELL_FAILED_NO_COMBO_POINTS
Definition SharedDefines.h:1038
@ SPELL_FAILED_ALREADY_HAVE_SUMMON
Definition SharedDefines.h:967
@ SPELL_FAILED_ALREADY_OPEN
Definition SharedDefines.h:968
@ SPELL_FAILED_NOT_TRADING
Definition SharedDefines.h:1031
@ SPELL_FAILED_NOTHING_TO_STEAL
Definition SharedDefines.h:1047
@ SPELL_FAILED_NO_MOUNTS_ALLOWED
Definition SharedDefines.h:1043
@ SPELL_FAILED_NOT_IN_BATTLEGROUND
Definition SharedDefines.h:1126
@ SPELL_FAILED_NOT_BEHIND
Definition SharedDefines.h:1017
@ SPELL_FAILED_ALREADY_HAVE_CHARM
Definition SharedDefines.h:966
@ SPELL_FAILED_TARGET_NOT_IN_INSTANCE
Definition SharedDefines.h:1097
@ SPELL_FAILED_HIGHLEVEL
Definition SharedDefines.h:996
@ SPELL_FAILED_LOWLEVEL
Definition SharedDefines.h:1008
@ SPELL_FAILED_NOT_READY
Definition SharedDefines.h:1027
@ SPELL_FAILED_ONLY_BATTLEGROUNDS
Definition SharedDefines.h:1102
@ SPELL_FAILED_NOT_IN_ARENA
Definition SharedDefines.h:1111
@ SPELL_FAILED_ITEM_ALREADY_ENCHANTED
Definition SharedDefines.h:1002
@ SPELL_FAILED_ONLY_STEALTHED
Definition SharedDefines.h:1055
@ SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED
Definition SharedDefines.h:1078
@ SPELL_FAILED_ONLY_ABOVEWATER
Definition SharedDefines.h:1048
@ SPELL_FAILED_CANT_BE_CHARMED
Definition SharedDefines.h:973
@ SPELL_FAILED_CASTER_DEAD
Definition SharedDefines.h:983
@ SPELL_FAILED_NOT_ON_MOUNTED
Definition SharedDefines.h:1115
@ SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW
Definition SharedDefines.h:1142
@ SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED
Definition SharedDefines.h:1146
@ SPELL_FAILED_TARGET_UNSKINNABLE
Definition SharedDefines.h:1086
@ SPELL_FAILED_NOT_SHAPESHIFT
Definition SharedDefines.h:1028
@ SPELL_FAILED_UNIQUE_GLYPH
Definition SharedDefines.h:1136
@ SPELL_FAILED_ONLY_OUTDOORS
Definition SharedDefines.h:1053
@ SPELL_FAILED_CHARMED
Definition SharedDefines.h:984
@ SPELL_FAILED_LINE_OF_SIGHT
Definition SharedDefines.h:1007
@ SPELL_FAILED_SPELL_IN_PROGRESS
Definition SharedDefines.h:1065
@ SPELL_FAILED_NO_PET
Definition SharedDefines.h:1044
@ SPELL_FAILED_NOPATH
Definition SharedDefines.h:1016
@ SPELL_FAILED_SPELL_UNAVAILABLE
Definition SharedDefines.h:1067
@ SPELL_FAILED_ONLY_INDOORS
Definition SharedDefines.h:1050
@ SPELL_FAILED_NOT_ON_TAXI
Definition SharedDefines.h:1025
@ SPELL_FAILED_TARGET_FRIENDLY
Definition SharedDefines.h:1075
@ SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS
Definition SharedDefines.h:558
@ SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND
Definition SharedDefines.h:557
@ SUMMON_CATEGORY_PET
Definition SharedDefines.h:3535
@ SUMMON_CATEGORY_PUPPET
Definition SharedDefines.h:3536
SkillType
Definition SharedDefines.h:3113
@ SKILL_MINING
Definition SharedDefines.h:3169
@ SKILL_HERBALISM
Definition SharedDefines.h:3165
@ SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE
Definition SharedDefines.h:627
@ SPELL_AURA_ABILITY_IGNORE_AURASTATE
Definition SpellAuraDefines.h:325
@ SPELL_AURA_MOD_SHAPESHIFT
Definition SpellAuraDefines.h:99
@ SPELL_AURA_MOD_IGNORE_SHAPESHIFT
Definition SpellAuraDefines.h:338
@ SPELL_AURA_PERIODIC_MANA_LEECH
Definition SpellAuraDefines.h:127
@ SPELL_AURA_MOD_POSSESS_PET
Definition SpellAuraDefines.h:191
@ SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS
Definition SpellAuraDefines.h:190
@ SPELL_AURA_DUMMY
Definition SpellAuraDefines.h:67
@ SPELL_AURA_FLY
Definition SpellAuraDefines.h:264
@ SPELL_AURA_HOVER
Definition SpellAuraDefines.h:169
@ SPELL_AURA_MOUNTED
Definition SpellAuraDefines.h:141
@ SPELL_AURA_AOE_CHARM
Definition SpellAuraDefines.h:240
@ SPELL_AURA_MOD_POSSESS
Definition SpellAuraDefines.h:65
@ SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED
Definition SpellAuraDefines.h:270
@ SPELL_AURA_BLOCK_SPELL_FAMILY
Definition SpellAuraDefines.h:360
@ AURA_INTERRUPT_FLAG_NOT_SEATED
Definition SpellDefines.h:61
@ AURA_INTERRUPT_FLAG_MOUNT
Definition SpellDefines.h:60
@ TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD
Will ignore GCD.
Definition SpellDefines.h:135
@ TRIGGERED_IGNORE_CASTER_AURASTATE
Will ignore shapeshift checks.
Definition SpellDefines.h:145
@ TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE
Will ignore caster aura states including combat requirements and death state.
Definition SpellDefines.h:146
@ TRIGGERED_IGNORE_SHAPESHIFT
Will not adjust facing to target (if any)
Definition SpellDefines.h:144
@ TRIGGERED_IGNORE_GCD
Not triggered.
Definition SpellDefines.h:134
@ TRIGGERED_IGNORE_EFFECTS
Periodic aura tick wont be reset on override.
Definition SpellDefines.h:153
@ TRIGGERED_IGNORE_CASTER_AURAS
Will ignore mounted/on vehicle restrictions.
Definition SpellDefines.h:147
std::vector< SpellImmune > SpellImmuneList
Definition SpellDefines.h:182
@ TARGET_FLAG_UNIT_ENEMY
Definition SpellInfo.h:54
@ TARGET_FLAG_ITEM
Definition SpellInfo.h:51
@ SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER
Definition SpellInfo.h:193
@ SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET
Definition SpellInfo.h:194
#define SPELL_RELIC_COOLDOWN
Definition SpellMgr.h:34
@ SPELL_FLAG_REDIRECTED
Definition Spell.h:85
TradeSlots
Definition TradeData.h:28
@ TRADE_SLOT_NONTRADED
Definition TradeData.h:31
@ MOVEMENTFLAG_FALLING_FAR
Definition UnitDefines.h:380
@ CLASS_CONTEXT_PET
Definition UnitDefines.h:238
@ UNIT_FLAG2_ALLOW_CHEAT_SPELLS
Definition UnitDefines.h:308
@ SHAPESHIFT_FLAG_STANCE
Definition UnitDefines.h:104
@ UNIT_STATE_ROOT
Definition UnitDefines.h:180
@ UNIT_STATE_CHARGING
Definition UnitDefines.h:187
@ UNIT_FLAG_SKINNABLE
Definition UnitDefines.h:278
#define WORLD_TRIGGER
Definition Unit.h:38
std::list< std::pair< Aura *, uint8 > > DispelChargesList
Definition Unit.h:78
Definition Battlefield.h:204
bool CanFlyIn()
Return if we can use mount in battlefield.
Definition Battlefield.h:341
Definition Battleground.h:294
Loot loot
Definition Creature.h:230
CreatureTemplate const * GetCreatureTemplate() const
Definition Creature.h:209
bool IsSpellProhibited(SpellSchoolMask idSchoolMask) const
Definition Creature.cpp:2844
Definition GameObject.h:120
GameObjectTemplate const * GetGOInfo() const
Definition GameObject.h:136
Definition GroupReference.h:27
GroupReference * next()
Definition GroupReference.h:36
Definition Group.h:169
Definition InstanceScript.h:143
bool IsLocked() const
Definition Item.h:253
ItemTemplate const * GetTemplate() const
Definition Item.cpp:544
bool IsPotion() const
Definition Item.h:337
bool IsDungeon() const
Definition Map.h:292
bool IsBattlegroundOrArena() const
Definition Map.h:300
GameObject * GetGameObject(ObjectGuid const guid)
Definition Map.cpp:2369
uint32 GetId() const
Definition Map.h:226
Difficulty GetDifficulty() const
Definition Map.h:287
uint64 GetRawValue() const
Definition ObjectGuid.h:142
bool IsPlayer() const
Definition ObjectGuid.h:168
bool IsGameObject() const
Definition ObjectGuid.h:171
Unit * ToUnit()
Definition Object.h:210
Definition PetDefines.h:209
Optional< PetInfo > CurrentPet
Definition PetDefines.h:232
std::vector< PetInfo > UnslottedPets
Definition PetDefines.h:235
Player * GetOwner() const
Definition Pet.cpp:2496
bool HaveInDiet(ItemTemplate const *item) const
Definition Pet.cpp:1442
uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel) const
Definition Pet.cpp:1460
static std::pair< PetStable::PetInfo const *, PetSaveMode > GetLoadPetInfo(PetStable const &stable, uint32 petEntry, uint32 petnumber, bool current)
Definition Pet.cpp:171
void SetCanTeleport(bool value)
Definition Player.h:2508
bool IsInSameRaidWith(Player const *p) const
Definition Player.h:1888
bool CanTameExoticPets() const
Definition Player.h:2196
bool CanUseBattlegroundObject(GameObject *gameobject) const
Definition Player.cpp:13243
bool InBattleground() const
Definition Player.h:2263
PetStable * GetPetStable()
Definition Player.h:1213
Battleground * GetBattleground(bool create=false) const
Definition Player.cpp:12223
WorldSession * GetSession() const
Definition Player.h:2005
bool HasSpellCooldown(uint32 spell_id) const override
Definition Player.cpp:16370
uint32 GetLastPotionId()
Definition Player.h:1814
Group * GetGroup()
Definition Player.h:2478
bool IsGameMaster() const
Definition Player.h:1166
time_t GetSummonExpireTimer() const
Definition Player.h:1109
bool Satisfy(DungeonProgressionRequirements const *ar, uint32 target_map, bool report=false)
Definition PlayerStorage.cpp:6713
bool HasPlayerFlag(PlayerFlags flags) const
Definition Player.h:1116
std::unique_ptr< DuelInfo > duel
Definition Player.h:1880
Item * GetItemByGuid(ObjectGuid guid) const
Definition PlayerStorage.cpp:407
GameObject * GetGOTarget() const
Definition Spell.cpp:264
ObjectGuid GetItemTargetGUID() const
Definition Spell.h:147
Definition SpellInfo.h:250
int32 MiscValue
Definition SpellInfo.h:264
uint32 ApplyAuraName
Definition SpellInfo.h:255
uint32 PreventionType
Definition SpellInfo.h:391
uint32 CasterAuraSpell
Definition SpellInfo.h:344
SpellCastResult CheckShapeshift(uint32 form) const
Definition SpellInfo.cpp:1429
uint32 Mechanic
Definition SpellInfo.h:324
uint32 GetDispelMask() const
Definition SpellInfo.cpp:2047
uint32 GetRecoveryTime() const
Definition SpellInfo.cpp:2403
bool IsSelfCast() const
Definition SpellInfo.cpp:1085
uint32 CasterAuraState
Definition SpellInfo.h:340
bool CanBeUsedInCombat() const
Definition SpellInfo.cpp:1227
uint32 CasterAuraStateNot
Definition SpellInfo.h:342
SpellCastResult CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player *player=nullptr, bool strict=true) const
Definition SpellInfo.cpp:1484
SpellSchoolMask GetSchoolMask() const
Definition SpellInfo.cpp:1993
int32 AreaGroupId
Definition SpellInfo.h:392
float GetMaxRange(bool positive=false, Unit *caster=nullptr, Spell *spell=nullptr) const
Definition SpellInfo.cpp:2330
uint32 GetExplicitTargetMask() const
Definition SpellInfo.cpp:2061
bool NeedsExplicitUnitTarget() const
Definition SpellInfo.cpp:1028
uint32 ExcludeCasterAuraSpell
Definition SpellInfo.h:346
uint32 SpellFamilyName
Definition SpellInfo.h:388
uint32 AuraInterruptFlags
Definition SpellInfo.h:354
SpellCastResult CheckExplicitTarget(Unit const *caster, WorldObject const *target, Item const *itemTarget=nullptr) const
Definition SpellInfo.cpp:1943
std::unique_ptr< PathGenerator > m_preGeneratedPath
Definition Spell.h:800
SpellCastResult CheckSpellFocus()
Definition Spell.cpp:7791
SpellCastResult CanOpenLock(uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
Definition Spell.cpp:8404
SpellCastResult CheckItems()
Definition Spell.cpp:7208
int32 CalculateSpellDamage(uint8 i, Unit const *target) const
Definition Spell.h:500
SpellCastResult CheckPower()
Definition Spell.cpp:7163
SpellCastResult CheckCasterAuras(bool preventionOnly) const
Definition Spell.cpp:6880
SpellCastResult CallScriptCheckCastHandlers()
Definition Spell.cpp:8612
bool IsTriggered() const
Definition Spell.h:576
SpellCastResult CheckRange(bool strict)
Definition Spell.cpp:7077
bool HasGlobalCooldown() const
Definition Spell.cpp:8884
Definition TemporarySummon.h:40
uint32 GetSpell() const
Definition TradeData.h:49
bool IsVehicle() const
Definition Unit.h:752
Vehicle * GetVehicle() const
Definition Unit.h:1842
Unit * GetOwner() const
Definition Unit.cpp:10695
Pet * ToPet()
Definition Unit.h:684
virtual bool HasSpellCooldown(uint32) const
Definition Unit.h:1264
ShapeshiftForm GetShapeshiftForm() const
Definition Unit.h:1873
virtual bool HasSpellItemCooldown(uint32, uint32) const
Definition Unit.h:1265
bool IsInDisallowedMountForm() const
Definition Unit.cpp:21127
void CombatStart(Unit *target, bool initialAggro=true)
Definition Unit.cpp:13720
bool HasUnitFlag2(UnitFlags2 flags) const
Definition Unit.h:708
bool IsInSanctuary() const
Definition Unit.h:984
virtual bool IsClass(Classes unitClass, ClassContext context=CLASS_CONTEXT_NONE) const
Definition Unit.h:796
AuraEffect * IsScriptOverriden(SpellInfo const *spell, int32 script) const
Definition Unit.cpp:5897
float GetCombatReach() const override
Definition Unit.h:824
UnitFlags GetUnitFlags() const
Definition Unit.h:701
TempSummon * ToTempSummon()
Definition Unit.h:686
bool HasStealthAura() const
Definition Unit.h:1758
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:5786
std::map< uint8, AuraApplication * > VisibleAuraMap
Definition Unit.h:642
bool IsInFlight() const
Definition Unit.h:1622
SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY]
Definition Unit.h:2008
void SendTameFailure(uint8 result)
Definition Unit.cpp:19829
void GetDispellableAuraList(Unit *caster, uint32 dispelMask, DispelChargesList &dispelList, SpellInfo const *dispelSpell)
Definition Unit.cpp:5670
bool HasUnitMovementFlag(uint32 f) const
Definition Unit.h:729
virtual bool IsInWater() const
Definition Unit.cpp:4404
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
Definition Unit.cpp:10642
bool isMoving() const
Definition Unit.h:1625
ObjectGuid GetCharmGUID() const
Definition Unit.h:676
VisibleAuraMap const * GetVisibleAuras()
Definition Unit.h:1460
bool IsMounted() const
Definition Unit.h:1803
Unit * GetVictim() const
Definition Unit.h:850
bool IsCritter() const
Definition Unit.h:785
ObjectGuid GetOwnerGUID() const
Definition Unit.h:668
uint8 GetComboPoints(Unit const *who=nullptr) const
Definition Unit.h:955
ObjectGuid GetCharmerGUID() const
Definition Unit.h:674
uint32 getTransForm() const
Definition Unit.h:1884
virtual bool HasActivePowerType(Powers power)
Definition Unit.h:1057
void RemoveMovementImpairingAuras(bool withRoot)
Definition Unit.cpp:5299
bool IsTotem() const
Definition Unit.h:751
Guardian * GetGuardianPet() const
Definition Unit.cpp:10746
ObjectGuid GetTarget() const
Definition Unit.h:813
bool IsInCombat() const
Definition Unit.h:881
ObjectGuid GetPetGUID() const
Definition Unit.h:678
Definition Vehicle.h:28
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger)
Definition Vehicle.cpp:598
uint32 GetMapId() const
Definition Position.h:280
Map * GetMap() const
Definition Object.h:621
InstanceScript * GetInstanceScript() const
Definition Object.cpp:1197
bool IsWithinLOSInMap(WorldObject const *obj, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, Optional< float > collisionHeight={ }, Optional< float > combatReach={ }) const
Definition Object.cpp:1352
bool IsOutdoors() const
Definition Object.cpp:3063
bool IsWithinLOS(float x, float y, float z, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS) const
Definition Object.cpp:1331
float GetVisibilityRange() const
Definition Object.cpp:1650
uint32 GetAreaId() const
Definition Object.cpp:3046
uint32 GetZoneId() const
Definition Object.cpp:3038
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition Object.cpp:3054
uint32 GetRecruiterId() const
Definition WorldSession.h:575
uint32 GetAccountId() const
Definition WorldSession.h:410
Seconds GetGameTime()
Definition GameTime.cpp:38
Player * FindPlayer(ObjectGuid const guid)
Definition ObjectAccessor.cpp:245
Definition DBCStructure.h:519
Definition ConditionMgr.h:183
Condition * mLastFailedCondition
Definition ConditionMgr.h:185
WorldObject * mConditionTargets[MAX_CONDITION_TARGETS]
Definition ConditionMgr.h:184
uint32 ErrorType
Definition ConditionMgr.h:206
uint8 ConditionTarget
Definition ConditionMgr.h:210
uint32 ErrorTextId
Definition ConditionMgr.h:207
SkillType GetRequiredLootSkill() const
Definition CreatureData.h:257
bool IsTameable(bool exotic) const
Definition CreatureData.h:274
uint32 type
Definition GameObjectData.h:33
Definition DBCStructure.h:1022
Definition Map.h:119
bool AllowMount
Definition Map.h:122
uint32 ItemLevel
Definition ItemTemplate.h:635
uint32 LockID
Definition ItemTemplate.h:669
uint32 InventoryType
Definition ItemTemplate.h:632
bool isLooted() const
Definition LootMgr.h:368
Definition DBCStructure.h:1326
bool IsDungeon() const
Definition DBCStructure.h:1352
void GetPosition(float &x, float &y) const
Definition Position.h:126
Definition DBCStructure.h:1818
uint32 flags1
Definition DBCStructure.h:1823
Definition DBCStructure.h:1910
uint32 Category
Definition DBCStructure.h:1912
Definition DBCStructure.h:2065
uint32 m_flags
Definition DBCStructure.h:2067

References InstanceTemplate::AllowMount, SpellEffectInfo::ApplyAuraName, AREA_FLAG_NO_FLY_ZONE, SpellInfo::AreaGroupId, AURA_INTERRUPT_FLAG_MOUNT, AURA_INTERRUPT_FLAG_NOT_SEATED, SpellInfo::AuraInterruptFlags, CalculateSpellDamage(), CallScriptCheckCastHandlers(), SpellInfo::CanBeUsedInCombat(), Battlefield::CanFlyIn(), CanOpenLock(), Player::CanTameExoticPets(), Player::CanUseBattlegroundObject(), SpellInfo::CasterAuraSpell, SpellInfo::CasterAuraState, SpellInfo::CasterAuraStateNot, Unit::CastSpell(), SummonPropertiesEntry::Category, CheckCasterAuras(), SpellInfo::CheckExplicitTarget(), CheckItems(), SpellInfo::CheckLocation(), CheckPower(), CheckRange(), SpellInfo::CheckShapeshift(), CheckSpellFocus(), SpellInfo::CheckTarget(), CLASS_CONTEXT_PET, CLASS_WARLOCK, Unit::CombatStart(), CONDITION_SOURCE_TYPE_SPELL, Condition::ConditionTarget, PetStable::CurrentPet, damage, Player::duel, EFFECT_0, SpellInfo::Effects, Condition::ErrorTextId, Condition::ErrorType, SpellInfo::ExcludeCasterAuraSpell, WorldObject::FindMap(), ObjectAccessor::FindPlayer(), SpellShapeshiftFormEntry::flags1, GAMEOBJECT_TYPE_DOOR, GAMEOBJECT_TYPE_TRAP, WorldSession::GetAccountId(), WorldObject::GetAreaId(), Unit::GetAuraEffectsByType(), Player::GetBattleground(), Unit::GetCharm(), Unit::GetCharmerGUID(), Unit::GetCharmGUID(), Unit::GetCombatReach(), Unit::GetComboPoints(), Creature::GetCreatureTemplate(), Pet::GetCurrentFoodBenefitLevel(), Map::GetDifficulty(), Unit::GetDispellableAuraList(), SpellInfo::GetDispelMask(), WorldObject::GetDistance(), SpellCastTargets::GetDstPos(), Object::GetEntry(), SpellInfo::GetExplicitTargetMask(), Map::GetGameObject(), GameTime::GetGameTime(), GameObject::GetGOInfo(), SpellCastTargets::GetGOTarget(), Player::GetGroup(), Unit::GetGuardianPet(), Map::GetId(), WorldObject::GetInstanceScript(), Player::GetItemByGuid(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetItemTargetGUID(), Player::GetLastPotionId(), Unit::GetLevel(), Pet::GetLoadPetInfo(), WorldObject::GetMap(), WorldLocation::GetMapId(), SpellInfo::GetMaxRange(), SpellCastTargets::GetObjectTarget(), Pet::GetOwner(), Player::GetPet(), Unit::GetPetGUID(), Player::GetPetStable(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), ObjectGuid::GetRawValue(), SpellInfo::GetRecoveryTime(), WorldSession::GetRecruiterId(), CreatureTemplate::GetRequiredLootSkill(), SpellInfo::GetSchoolMask(), Vehicle::GetSeatForPassenger(), Player::GetSession(), Unit::GetShapeshiftForm(), Player::GetSkillValue(), TradeData::GetSpell(), Player::GetSummonExpireTimer(), Unit::GetTarget(), SpellCastTargets::GetTargetMask(), Item::GetTemplate(), Player::GetTradeData(), Unit::getTransForm(), Unit::GetUnitFlags(), SpellCastTargets::GetUnitTarget(), Unit::GetVehicle(), Unit::GetVictim(), WorldObject::GetVisibilityRange(), Unit::GetVisibleAuras(), WorldObject::GetZoneAndAreaId(), WorldObject::GetZoneId(), GO_STATE_READY, Unit::HasActivePowerType(), SpellInfo::HasAttribute(), SpellInfo::HasAura(), Unit::HasAura(), Unit::HasAuraState(), SpellCastTargets::HasDst(), SpellInfo::HasEffect(), HasGlobalCooldown(), Player::HasPlayerFlag(), Player::HasSpellCooldown(), Unit::HasSpellCooldown(), Unit::HasSpellItemCooldown(), Unit::HasStealthAura(), HasTriggeredCastFlag(), Unit::HasUnitFlag2(), Unit::HasUnitMovementFlag(), Unit::HasUnitState(), Pet::HaveInDiet(), HUNTER_PET, SpellInfo::Id, IMMUNITY_MECHANIC, IN_MILLISECONDS, Player::InBattleground(), ItemTemplate::InventoryType, INVTYPE_RELIC, irand(), Unit::IsAlive(), IsAutoRepeat(), Map::IsBattlegroundOrArena(), Unit::IsClass(), SpellInfo::IsCooldownStartedOnEvent(), Object::IsCreature(), Unit::IsCritter(), Map::IsDungeon(), MapEntry::IsDungeon(), Unit::IsFriendlyTo(), Player::IsGameMaster(), ObjectGuid::IsGameObject(), Unit::IsInCombat(), Unit::IsInDisallowedMountForm(), Unit::IsInFlight(), Player::IsInSameRaidWith(), Unit::IsInSanctuary(), Unit::IsInWater(), Item::IsLocked(), Loot::isLooted(), Unit::IsMounted(), Unit::isMoving(), IsNextMeleeSwingSpell(), WorldObject::IsOutdoors(), SpellInfo::IsPassive(), Object::IsPlayer(), SpellInfo::IsPositive(), Item::IsPotion(), Unit::IsScriptOverriden(), SpellInfo::IsSelfCast(), Creature::IsSpellProhibited(), CreatureTemplate::IsTameable(), Unit::IsTotem(), IsTriggered(), WorldObject::IsWithinLOS(), WorldObject::IsWithinLOSInMap(), ItemTemplate::ItemLevel, LINEOFSIGHT_ALL_CHECKS, ItemTemplate::LockID, Creature::loot, VMAP::M2, m_caster, m_CastItem, m_customError, VehicleSeatEntry::m_flags, m_needComboPoints, m_originalCaster, m_originalCasterGUID, m_preGeneratedPath, m_selfContainer, m_spellFlags, Unit::m_spellImmune, m_spellInfo, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, ConditionSourceInfo::mConditionTargets, SpellInfo::Mechanic, MINUTE, SpellEffectInfo::MiscValue, ConditionSourceInfo::mLastFailedCondition, MOVEMENTFLAG_FALLING_FAR, SpellInfo::NeedsExplicitUnitTarget(), GroupReference::next(), PATHFIND_INCOMPLETE, PATHFIND_NOPATH, PATHFIND_SHORT, PET_TAME_CANT_CONTROL_EXOTIC, PET_TAME_DEAD, PET_TAME_NOPET_AVAILABLE, PLAYER_ALLOW_ONLY_ABILITY, POWER_MANA, SpellInfo::PreventionType, Unit::RemoveMovementImpairingAuras(), sAreaTableStore, Player::Satisfy(), sBattlefieldMgr, sConditionMgr, sDisableMgr, Unit::SendTameFailure(), sGlyphPropertiesStore, SHAPESHIFT_FLAG_STANCE, SKILL_HERBALISM, SKILL_LOCKPICKING, SKILL_MINING, SKILL_NONE, sMapStore, sObjectMgr, SPECTATOR_SPELL_BINDSIGHT, SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD, SPELL_ATTR0_ALLOW_WHILE_MOUNTED, SPELL_ATTR0_AURA_IS_DEBUFF, SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET, SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER, SPELL_ATTR0_NO_IMMUNITIES, SPELL_ATTR0_ONLY_INDOORS, SPELL_ATTR0_ONLY_OUTDOORS, SPELL_ATTR0_ONLY_STEALTHED, SPELL_ATTR0_PASSIVE, SPELL_ATTR1_DISMISS_PET_FIRST, SPELL_ATTR1_INITIATE_COMBAT, SPELL_ATTR2_IGNORE_LINE_OF_SIGHT, SPELL_ATTR3_ONLY_BATTLEGROUNDS, SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS, SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND, SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT, SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE, SPELL_ATTR7_DEBUG_SPELL, SPELL_AURA_ABILITY_IGNORE_AURASTATE, SPELL_AURA_AOE_CHARM, SPELL_AURA_BLOCK_SPELL_FAMILY, SPELL_AURA_DUMMY, SPELL_AURA_FLY, SPELL_AURA_HOVER, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_IGNORE_SHAPESHIFT, SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED, SPELL_AURA_MOD_POSSESS, SPELL_AURA_MOD_POSSESS_PET, SPELL_AURA_MOD_SHAPESHIFT, SPELL_AURA_MOUNTED, SPELL_AURA_PERIODIC_MANA_LEECH, SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS, SPELL_CAST_OK, SPELL_CUSTOM_ERROR_GM_ONLY, SPELL_EFFECT_APPLY_GLYPH, SPELL_EFFECT_CHARGE, SPELL_EFFECT_CREATE_TAMED_PET, SPELL_EFFECT_DISPEL, SPELL_EFFECT_FEED_PET, SPELL_EFFECT_JUMP, SPELL_EFFECT_JUMP_DEST, SPELL_EFFECT_LEAP, SPELL_EFFECT_LEAP_BACK, SPELL_EFFECT_LEARN_PET_SPELL, SPELL_EFFECT_LEARN_SPELL, SPELL_EFFECT_OPEN_LOCK, SPELL_EFFECT_POWER_BURN, SPELL_EFFECT_POWER_DRAIN, SPELL_EFFECT_RESURRECT, SPELL_EFFECT_RESURRECT_NEW, SPELL_EFFECT_RESURRECT_PET, SPELL_EFFECT_SKINNING, SPELL_EFFECT_STEAL_BENEFICIAL_BUFF, SPELL_EFFECT_STUCK, SPELL_EFFECT_SUMMON, SPELL_EFFECT_SUMMON_PET, SPELL_EFFECT_SUMMON_PLAYER, SPELL_EFFECT_SUMMON_RAF_FRIEND, SPELL_EFFECT_TALENT_SPEC_SELECT, SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER, SPELL_FAILED_AFFECTING_COMBAT, SPELL_FAILED_ALREADY_HAVE_CHARM, SPELL_FAILED_ALREADY_HAVE_SUMMON, SPELL_FAILED_ALREADY_OPEN, SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_CANT_BE_CHARMED, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_CASTER_DEAD, SPELL_FAILED_CHARMED, SPELL_FAILED_CUSTOM_ERROR, SPELL_FAILED_DAMAGE_IMMUNE, SPELL_FAILED_DONT_REPORT, SPELL_FAILED_FOOD_LOWLEVEL, SPELL_FAILED_HIGHLEVEL, SPELL_FAILED_ITEM_ALREADY_ENCHANTED, SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW, SPELL_FAILED_LINE_OF_SIGHT, SPELL_FAILED_LOW_CASTLEVEL, SPELL_FAILED_LOWLEVEL, SPELL_FAILED_MOVING, SPELL_FAILED_NO_COMBO_POINTS, SPELL_FAILED_NO_MOUNTS_ALLOWED, SPELL_FAILED_NO_PET, SPELL_FAILED_NOPATH, SPELL_FAILED_NOT_BEHIND, SPELL_FAILED_NOT_HERE, SPELL_FAILED_NOT_IN_ARENA, SPELL_FAILED_NOT_IN_BATTLEGROUND, SPELL_FAILED_NOT_INFRONT, SPELL_FAILED_NOT_KNOWN, SPELL_FAILED_NOT_MOUNTED, SPELL_FAILED_NOT_ON_MOUNTED, SPELL_FAILED_NOT_ON_TAXI, SPELL_FAILED_NOT_READY, SPELL_FAILED_NOT_SHAPESHIFT, SPELL_FAILED_NOT_TRADING, SPELL_FAILED_NOTHING_TO_DISPEL, SPELL_FAILED_NOTHING_TO_STEAL, SPELL_FAILED_ONLY_ABOVEWATER, SPELL_FAILED_ONLY_BATTLEGROUNDS, SPELL_FAILED_ONLY_INDOORS, SPELL_FAILED_ONLY_OUTDOORS, SPELL_FAILED_ONLY_STEALTHED, SPELL_FAILED_ROOTED, SPELL_FAILED_SPELL_IN_PROGRESS, SPELL_FAILED_SPELL_UNAVAILABLE, SPELL_FAILED_SUMMON_PENDING, SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED, SPELL_FAILED_TARGET_FRIENDLY, SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED, SPELL_FAILED_TARGET_NOT_IN_INSTANCE, SPELL_FAILED_TARGET_NOT_LOOTED, SPELL_FAILED_TARGET_UNSKINNABLE, SPELL_FAILED_TRY_AGAIN, SPELL_FAILED_UNIQUE_GLYPH, SPELL_FAILED_WRONG_PET_FOOD, SPELL_FLAG_REDIRECTED, SPELL_PREVENTION_TYPE_NONE, SPELL_RELIC_COOLDOWN, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyName, TriggeredByAuraSpellData::spellInfo, SpellInfo::SpellLevel, sScriptMgr, sSpellMgr, sSpellShapeshiftFormStore, sSummonPropertiesStore, STATUS_IN_PROGRESS, STATUS_WAIT_LEAVE, SUMMON_CATEGORY_PET, SUMMON_CATEGORY_PUPPET, TARGET_FLAG_ITEM, TARGET_FLAG_TRADE_ITEM, TARGET_FLAG_UNIT_ENEMY, TARGET_GAMEOBJECT_ITEM_TARGET, TARGET_GAMEOBJECT_TARGET, TARGET_UNIT_PET, Object::ToCreature(), Unit::ToPet(), Object::ToPlayer(), Unit::ToTempSummon(), Object::ToUnit(), TRADE_SLOT_NONTRADED, TRIGGERED_IGNORE_CASTER_AURAS, TRIGGERED_IGNORE_CASTER_AURASTATE, TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE, TRIGGERED_IGNORE_EFFECTS, TRIGGERED_IGNORE_GCD, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, TRIGGERED_IGNORE_SHAPESHIFT, TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD, GameObjectTemplate::type, UNIT_FLAG2_ALLOW_CHEAT_SPELLS, UNIT_FLAG_SKINNABLE, UNIT_STATE_CHARGING, UNIT_STATE_ROOT, unitTarget, PetStable::UnslottedPets, VEHICLE_SEAT_FLAG_CAN_ATTACK, VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL, VEHICLE_SEAT_FLAG_UNCONTROLLED, and WORLD_TRIGGER.

Referenced by _cast(), Unit::_UpdateAutoRepeatSpell(), Unit::AttackerStateUpdate(), Player::CastItemUseSpell(), CheckPetCast(), WorldSession::HandleAcceptTradeOpcode(), prepare(), and go_wind_stone::go_wind_stoneAI::SummonNPC().

◆ CheckCasterAuras()

SpellCastResult Spell::CheckCasterAuras ( bool  preventionOnly) const
6881{
6882 // spells totally immuned to caster auras (wsg flag drop, give marks etc)
6884 return SPELL_CAST_OK;
6885
6886 uint8 school_immune = 0;
6887 uint32 mechanic_immune = 0;
6888 uint32 dispel_immune = 0;
6889
6890 // Check if the spell grants school or mechanic immunity.
6891 // We use bitmasks so the loop is done only once and not on every aura check below.
6893 {
6894 for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
6895 {
6896 if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_SCHOOL_IMMUNITY)
6897 school_immune |= uint32(m_spellInfo->Effects[i].MiscValue);
6898 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MECHANIC_IMMUNITY)
6899 mechanic_immune |= 1 << uint32(m_spellInfo->Effects[i].MiscValue);
6900 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_DISPEL_IMMUNITY)
6901 dispel_immune |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6902 }
6903 // immune movement impairment and loss of control
6904 // PVP trinket EMFH TOC PVP trinket Bullheaded Bestial Wrath // Beath Within // Medalion of Immunity
6905 if (m_spellInfo->Id == 42292 || m_spellInfo->Id == 59752 || m_spellInfo->Id == 65547 || m_spellInfo->Id == 53490 || m_spellInfo->Id == 19574 || m_spellInfo->Id == 34471 || m_spellInfo->Id == 46227)
6907 }
6908
6910
6911 // Glyph of Pain Suppression
6912 // there is no other way to handle it
6913 if (m_spellInfo->Id == 33206 && !m_caster->HasAura(63248))
6914 usableInStun = false;
6915
6916 // Check whether the cast should be prevented by any state you might have.
6917 SpellCastResult prevented_reason = SPELL_CAST_OK;
6918 // Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out
6919 uint32 unitflag = m_caster->GetUnitFlags(); // Get unit state
6920
6921 // Xinef: if spell is triggered check preventionType only
6922 if (!preventionOnly)
6923 {
6924 if (unitflag & UNIT_FLAG_STUNNED)
6925 {
6926 // spell is usable while stunned, check if caster has only mechanic stun auras, another stun types must prevent cast spell
6927 if (usableInStun)
6928 {
6929 bool foundNotStun = false;
6930 uint32 mask = (1 << MECHANIC_STUN) | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_HORROR);
6931 // Barkskin should skip sleep effects, sap and fears
6932 if (m_spellInfo->Id == 22812)
6933 mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << MECHANIC_SLEEP;
6934 // Hand of Freedom, can be used while sapped
6935 if (m_spellInfo->Id == 1044)
6936 mask |= 1 << MECHANIC_SAPPED;
6938 for (Unit::AuraEffectList::const_iterator i = stunAuras.begin(); i != stunAuras.end(); ++i)
6939 {
6940 if ((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() && !((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() & mask))
6941 {
6942 foundNotStun = true;
6943 break;
6944 }
6945 }
6946 if (foundNotStun)
6947 prevented_reason = SPELL_FAILED_STUNNED;
6948 }
6949 else
6950 prevented_reason = SPELL_FAILED_STUNNED;
6951 }
6953 prevented_reason = SPELL_FAILED_CONFUSED;
6955 prevented_reason = SPELL_FAILED_FLEEING;
6956 }
6957
6958 // Xinef: if there is no prevented_reason, check prevention types
6959 if (prevented_reason == SPELL_CAST_OK)
6960 {
6962 prevented_reason = SPELL_FAILED_SILENCED;
6964 prevented_reason = SPELL_FAILED_PACIFIED;
6965 }
6966
6967 // Attr must make flag drop spell totally immune from all effects
6968 if (prevented_reason != SPELL_CAST_OK)
6969 {
6970 if (school_immune || mechanic_immune || dispel_immune)
6971 {
6972 //Checking auras is needed now, because you are prevented by some state but the spell grants immunity.
6974 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
6975 {
6976 Aura const* aura = itr->second->GetBase();
6977 SpellInfo const* auraInfo = aura->GetSpellInfo();
6978 if (auraInfo->GetAllEffectsMechanicMask() & mechanic_immune)
6979 continue;
6980 if (auraInfo->GetSchoolMask() & school_immune && !auraInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS))
6981 continue;
6982 if (auraInfo->GetDispelMask() & dispel_immune)
6983 continue;
6984
6985 //Make a second check for spell failed so the right SPELL_FAILED message is returned.
6986 //That is needed when your casting is prevented by multiple states and you are only immune to some of them.
6987 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6988 {
6989 if (AuraEffect* part = aura->GetEffect(i))
6990 {
6991 switch (part->GetAuraType())
6992 {
6994 {
6995 uint32 mask = 1 << MECHANIC_STUN;
6996 // Barkskin should skip sleep effects, sap and fears
6997 if (m_spellInfo->Id == 22812)
6998 mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << MECHANIC_SLEEP;
6999 // Hand of Freedom, can be used while sapped
7000 if (m_spellInfo->Id == 1044)
7001 mask |= 1 << MECHANIC_SAPPED;
7002
7003 if (!usableInStun || !(auraInfo->GetAllEffectsMechanicMask() & mask))
7004 return SPELL_FAILED_STUNNED;
7005 break;
7006 }
7009 return SPELL_FAILED_CONFUSED;
7010 break;
7013 return SPELL_FAILED_FLEEING;
7014 break;
7019 return SPELL_FAILED_PACIFIED;
7021 return SPELL_FAILED_SILENCED;
7022 break;
7023 default:
7024 break;
7025 }
7026 }
7027 }
7028 }
7029 }
7030 // You are prevented from casting and the spell casted does not grant immunity. Return a failed error.
7031 else
7032 return prevented_reason;
7033 }
7034 return SPELL_CAST_OK;
7035}
@ SPELL_PREVENTION_TYPE_SILENCE
Definition SharedDefines.h:1565
@ SPELL_PREVENTION_TYPE_PACIFY
Definition SharedDefines.h:1566
@ SPELL_ATTR5_ALLOW_WHILE_STUNNED
Definition SharedDefines.h:581
@ SPELL_ATTR5_ALLOW_WHILE_FLEEING
Definition SharedDefines.h:595
@ SPELL_ATTR5_ALLOW_WHILE_CONFUSED
Definition SharedDefines.h:596
@ SPELL_ATTR1_IMMUNITY_PURGES_EFFECT
Definition SharedDefines.h:445
@ SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS
Definition SharedDefines.h:446
@ MECHANIC_STUN
Definition SharedDefines.h:1348
@ MECHANIC_FREEZE
Definition SharedDefines.h:1349
@ MECHANIC_SLEEP
Definition SharedDefines.h:1346
@ MECHANIC_SAPPED
Definition SharedDefines.h:1366
@ MECHANIC_HORROR
Definition SharedDefines.h:1360
#define IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK
Definition SharedDefines.h:1372
@ SPELL_FAILED_STUNNED
Definition SharedDefines.h:1068
@ SPELL_FAILED_CONFUSED
Definition SharedDefines.h:986
@ SPELL_FAILED_SILENCED
Definition SharedDefines.h:1064
@ SPELL_FAILED_FLEEING
Definition SharedDefines.h:994
@ SPELL_FAILED_PACIFIED
Definition SharedDefines.h:1058
@ SPELL_ATTR6_NOT_AN_ATTACK
Definition SharedDefines.h:617
@ SPELL_AURA_DISPEL_IMMUNITY
Definition SpellAuraDefines.h:104
@ SPELL_AURA_MOD_FEAR
Definition SpellAuraDefines.h:70
@ SPELL_AURA_MOD_PACIFY
Definition SpellAuraDefines.h:88
@ SPELL_AURA_MOD_SILENCE
Definition SpellAuraDefines.h:90
@ SPELL_AURA_SCHOOL_IMMUNITY
Definition SpellAuraDefines.h:102
@ SPELL_AURA_MECHANIC_IMMUNITY
Definition SpellAuraDefines.h:140
@ SPELL_AURA_MOD_PACIFY_SILENCE
Definition SpellAuraDefines.h:123
@ SPELL_AURA_MOD_CONFUSE
Definition SpellAuraDefines.h:68
@ SPELL_AURA_MOD_STUN
Definition SpellAuraDefines.h:75
@ UNIT_FLAG_STUNNED
Definition UnitDefines.h:270
@ UNIT_FLAG_PACIFIED
Definition UnitDefines.h:269
@ UNIT_FLAG_CONFUSED
Definition UnitDefines.h:274
@ UNIT_FLAG_FLEEING
Definition UnitDefines.h:275
@ UNIT_FLAG_SILENCED
Definition UnitDefines.h:265
Definition SpellAuras.h:87
AuraEffect * GetEffect(uint8 effIndex) const
Definition SpellAuras.h:175
SpellInfo const * GetSpellInfo() const
Definition SpellAuras.h:100
uint32 GetAllEffectsMechanicMask() const
Definition SpellInfo.cpp:1998
std::multimap< uint32, AuraApplication * > AuraApplicationMap
Definition Unit.h:629
AuraApplicationMap & GetAppliedAuras()
Definition Unit.h:1308

References SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Unit::GetAppliedAuras(), Unit::GetAuraEffectsByType(), SpellInfo::GetDispelMask(), Aura::GetEffect(), SpellInfo::GetSchoolMask(), Aura::GetSpellInfo(), Unit::GetUnitFlags(), SpellInfo::HasAttribute(), Unit::HasAura(), SpellInfo::Id, IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK, m_caster, m_spellInfo, MAX_SPELL_EFFECTS, MECHANIC_FREEZE, MECHANIC_HORROR, MECHANIC_SAPPED, MECHANIC_SLEEP, MECHANIC_STUN, SpellInfo::PreventionType, SPELL_ATTR1_IMMUNITY_PURGES_EFFECT, SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS, SPELL_ATTR5_ALLOW_WHILE_CONFUSED, SPELL_ATTR5_ALLOW_WHILE_FLEEING, SPELL_ATTR5_ALLOW_WHILE_STUNNED, SPELL_ATTR6_NOT_AN_ATTACK, SPELL_AURA_DISPEL_IMMUNITY, SPELL_AURA_MECHANIC_IMMUNITY, SPELL_AURA_MOD_CONFUSE, SPELL_AURA_MOD_FEAR, SPELL_AURA_MOD_PACIFY, SPELL_AURA_MOD_PACIFY_SILENCE, SPELL_AURA_MOD_SILENCE, SPELL_AURA_MOD_STUN, SPELL_AURA_SCHOOL_IMMUNITY, SPELL_CAST_OK, SPELL_FAILED_CONFUSED, SPELL_FAILED_FLEEING, SPELL_FAILED_PACIFIED, SPELL_FAILED_SILENCED, SPELL_FAILED_STUNNED, SPELL_PREVENTION_TYPE_PACIFY, SPELL_PREVENTION_TYPE_SILENCE, UNIT_FLAG_CONFUSED, UNIT_FLAG_FLEEING, UNIT_FLAG_PACIFIED, UNIT_FLAG_SILENCED, and UNIT_FLAG_STUNNED.

Referenced by CheckCast().

◆ CheckDst()

void Spell::CheckDst ( )
inline
void SetDst(float x, float y, float z, float orientation, uint32 mapId=MAPID_INVALID)
Definition Spell.cpp:406

References SpellCastTargets::HasDst(), m_caster, m_targets, and SpellCastTargets::SetDst().

Referenced by SelectEffectImplicitTargets(), and SelectImplicitDestDestTargets().

◆ CheckEffectExecuteData()

void Spell::CheckEffectExecuteData ( )
protected
8546{
8547 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8549}
#define ASSERT
Definition Errors.h:68

References ASSERT, m_effectExecuteData, and MAX_SPELL_EFFECTS.

Referenced by PrepareTargetProcessing(), and ~Spell().

◆ CheckEffectTarget()

bool Spell::CheckEffectTarget ( Unit const *  target,
uint32  eff 
) const
Todo:
: below shouldn't be here, but it's temporary
7969{
7970 switch (m_spellInfo->Effects[eff].ApplyAuraName)
7971 {
7976 if (target->IsCreature() && target->IsVehicle())
7977 return false;
7978 if (target->IsMounted())
7979 return false;
7980 if (target->GetCharmerGUID())
7981 return false;
7982 if (int32 damage = CalculateSpellDamage(eff, target))
7983 if ((int32)target->GetLevel() > damage)
7984 return false;
7985 break;
7986 default:
7987 break;
7988 }
7989
7990 // xinef: skip los checking if spell has appropriate attribute, or target requires specific entry
7991 // this is only for target addition and target has to have unselectable flag, this is valid for FLAG_EXTRA_TRIGGER and quest triggers however there are some without this flag, used not_selectable
7992 if (m_spellInfo->HasAttribute(SPELL_ATTR2_IGNORE_LINE_OF_SIGHT) || (target->IsCreature() && target->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE) && (m_spellInfo->Effects[eff].TargetA.GetCheckType() == TARGET_CHECK_ENTRY || m_spellInfo->Effects[eff].TargetB.GetCheckType() == TARGET_CHECK_ENTRY)))
7993 return true;
7994
7995 // if spell is triggered, need to check for LOS disable on the aura triggering it and inherit that behaviour
7998 {
7999 return true;
8000 }
8001
8003 //Check targets for LOS visibility (except spells without range limitations)
8004 switch (m_spellInfo->Effects[eff].Effect)
8005 {
8007 // player far away, maybe his corpse near?
8008 if (target != m_caster && !target->IsWithinLOSInMap(m_caster))
8009 {
8011 return false;
8012
8014 if (!corpse)
8015 return false;
8016
8017 if (target->GetGUID() != corpse->GetOwnerGUID())
8018 return false;
8019
8021 return false;
8022 }
8023 break;
8025 {
8027 {
8028 if (target->IsWithinLOSInMap(m_caster, VMAP::ModelIgnoreFlags::M2) && target->HasUnitFlag(UNIT_FLAG_SKINNABLE))
8029 return true;
8030
8031 return false;
8032 }
8033
8035 if (!corpse)
8036 return false;
8037
8038 if (target->GetGUID() != corpse->GetOwnerGUID())
8039 return false;
8040
8042 return false;
8043
8045 return false;
8046 }
8047 break;
8049 if (!m_caster->IsPlayer() || !target->IsPlayer())
8050 return false;
8051 if (m_caster->ToPlayer()->GetSession()->IsARecruiter() && target->ToPlayer()->GetSession()->GetRecruiterId() != m_caster->ToPlayer()->GetSession()->GetAccountId())
8052 return false;
8053 if (m_caster->ToPlayer()->GetSession()->GetRecruiterId() != target->ToPlayer()->GetSession()->GetAccountId() && target->ToPlayer()->GetSession()->IsARecruiter())
8054 return false;
8055 if (target->ToPlayer()->GetLevel() >= sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL))
8056 return false;
8057 break;
8058 default: // normal case
8059 {
8060 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
8061 GameObject* gobCaster = nullptr;
8063 {
8065 }
8066 else if (m_caster->GetEntry() == WORLD_TRIGGER)
8067 {
8068 if (TempSummon* tempSummon = m_caster->ToTempSummon())
8069 {
8070 gobCaster = tempSummon->GetSummonerGameObject();
8071 }
8072 }
8073
8074 if (gobCaster)
8075 {
8076 if (gobCaster->GetGOInfo()->IsIgnoringLOSChecks())
8077 {
8078 return true;
8079 }
8080
8081 // If spell casted by gameobject then ignore M2 models
8082 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
8083 }
8084
8085 if (target != m_caster)
8086 {
8087 if (m_targets.HasDst())
8088 {
8089 float x = m_targets.GetDstPos()->GetPositionX();
8090 float y = m_targets.GetDstPos()->GetPositionY();
8091 float z = m_targets.GetDstPos()->GetPositionZ();
8092
8093 if (!target->IsWithinLOS(x, y, z, VMAP::ModelIgnoreFlags::M2, LineOfSightChecks(losChecks)))
8094 {
8095 return false;
8096 }
8097 }
8099 {
8100 return false;
8101 }
8102 }
8103 break;
8104 }
8105 }
8106
8107 return true;
8108}
@ CORPSE_FLAG_LOOTABLE
Definition Corpse.h:45
@ SPELL_DISABLE_LOS
Definition DisableMgr.h:50
@ DISABLE_TYPE_SPELL
Definition DisableMgr.h:28
@ SPELL_EFFECT_SKIN_PLAYER_CORPSE
Definition SharedDefines.h:905
@ TARGET_CHECK_ENTRY
Definition SpellInfo.h:116
@ UNIT_FLAG_NOT_SELECTABLE
Definition UnitDefines.h:277
@ CORPSE_FIELD_FLAGS
Definition UpdateFields.h:427
@ CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL
Definition WorldConfig.h:200
Definition Corpse.h:49
ObjectGuid GetOwnerGUID() const
Definition Corpse.h:68
bool HasFlag(uint16 index, uint32 flag) const
Definition Object.cpp:878
ObjectGuid GetCorpseTargetGUID() const
Definition Spell.cpp:281
bool IsARecruiter() const
Definition WorldSession.h:576
#define sWorld
Definition World.h:317
Corpse * GetCorpse(WorldObject const &u, ObjectGuid const guid)
Definition ObjectAccessor.cpp:179
bool IsIgnoringLOSChecks() const
Definition GameObjectData.h:644

References CalculateSpellDamage(), CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL, CORPSE_FIELD_FLAGS, CORPSE_FLAG_LOOTABLE, damage, DISABLE_TYPE_SPELL, SpellInfo::Effects, WorldSession::GetAccountId(), Unit::GetCharmerGUID(), ObjectAccessor::GetCorpse(), SpellCastTargets::GetCorpseTargetGUID(), SpellCastTargets::GetDstPos(), Object::GetEntry(), Map::GetGameObject(), GameObject::GetGOInfo(), Object::GetGUID(), Unit::GetLevel(), WorldObject::GetMap(), Corpse::GetOwnerGUID(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), WorldSession::GetRecruiterId(), Player::GetSession(), SpellInfo::HasAttribute(), SpellCastTargets::HasDst(), Object::HasFlag(), Unit::HasUnitFlag(), SpellInfo::Id, WorldSession::IsARecruiter(), Object::IsCreature(), ObjectGuid::IsGameObject(), GameObjectTemplate::IsIgnoringLOSChecks(), Unit::IsMounted(), Object::IsPlayer(), IsTriggered(), Unit::IsVehicle(), WorldObject::IsWithinLOS(), WorldObject::IsWithinLOSInMap(), LINEOFSIGHT_ALL_CHECKS, VMAP::M2, m_caster, m_originalCasterGUID, m_spellFlags, m_spellInfo, m_targets, m_triggeredByAuraSpell, sDisableMgr, SPELL_ATTR2_IGNORE_LINE_OF_SIGHT, SPELL_AURA_AOE_CHARM, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_POSSESS, SPELL_AURA_MOD_POSSESS_PET, SPELL_DISABLE_LOS, SPELL_EFFECT_RESURRECT_NEW, SPELL_EFFECT_SKIN_PLAYER_CORPSE, SPELL_EFFECT_SUMMON_RAF_FRIEND, SPELL_FLAG_REDIRECTED, TriggeredByAuraSpellData::spellInfo, sWorld, TARGET_CHECK_ENTRY, Object::ToPlayer(), Unit::ToTempSummon(), UNIT_FLAG_NOT_SELECTABLE, UNIT_FLAG_SKINNABLE, and WORLD_TRIGGER.

Referenced by AddUnitTarget().

◆ CheckItems()

SpellCastResult Spell::CheckItems ( )
Todo:
Needs review
Todo:
: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
7209{
7210 Player* player = m_caster->ToPlayer();
7211 if (!player)
7212 {
7213 // Non-player case: Check if creature is disarmed
7215 {
7217 }
7218
7219 return SPELL_CAST_OK;
7220 }
7221
7222 if (!m_CastItem)
7223 {
7224 if (m_castItemGUID)
7226 }
7227 else
7228 {
7229 uint32 itemid = m_CastItem->GetEntry();
7230 if (!player->HasItemCount(itemid))
7232
7233 ItemTemplate const* proto = m_CastItem->GetTemplate();
7234 if (!proto)
7236
7237 for (int i = 0; i < MAX_ITEM_SPELLS; ++i)
7238 if (proto->Spells[i].SpellCharges)
7239 if (m_CastItem->GetSpellCharges(i) == 0)
7241
7242 // consumable cast item checks
7244 {
7245 // such items should only fail if there is no suitable effect at all - see Rejuvenation Potions for example
7246 SpellCastResult failReason = SPELL_CAST_OK;
7247 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
7248 {
7249 // skip check, pet not required like checks, and for TARGET_UNIT_PET m_targets.GetUnitTarget() is not the real target but the caster
7250 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_PET)
7251 continue;
7252
7253 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_HEAL)
7254 {
7256 {
7258 continue;
7259 }
7260 else
7261 {
7262 failReason = SPELL_CAST_OK;
7263 break;
7264 }
7265 }
7266
7267 // Mana Potion, Rage Potion, Thistle Tea(Rogue), ...
7268 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_ENERGIZE)
7269 {
7270 if (m_spellInfo->Effects[i].MiscValue < 0 || m_spellInfo->Effects[i].MiscValue >= int8(MAX_POWERS))
7271 {
7273 continue;
7274 }
7275
7276 Powers power = Powers(m_spellInfo->Effects[i].MiscValue);
7278 {
7280 continue;
7281 }
7282 else
7283 {
7284 failReason = SPELL_CAST_OK;
7285 break;
7286 }
7287 }
7288 }
7289 if (failReason != SPELL_CAST_OK)
7290 return failReason;
7291 }
7292 }
7293
7294 // check target item
7296 {
7297 if (!m_caster->IsPlayer())
7299
7300 if (!m_targets.GetItemTarget())
7302
7305 }
7306 // if not item target then required item must be equipped
7307 else
7308 {
7309 // Xinef: this is not true in my opinion, in eg bladestorm will not be canceled after disarm
7310 //if (!HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT))
7313 }
7314
7315 // do not take reagents for these item casts
7317 {
7319 // Not own traded item (in trader trade slot) requires reagents even if triggered spell
7320 if (!checkReagents)
7321 if (Item* targetItem = m_targets.GetItemTarget())
7322 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
7323 checkReagents = true;
7324
7325 // check reagents (ignore triggered spells with reagents processed by original spell) and special reagent ignore case.
7326 if (checkReagents)
7327 {
7328 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
7329 {
7330 if (m_spellInfo->Reagent[i] <= 0)
7331 continue;
7332
7333 uint32 itemid = m_spellInfo->Reagent[i];
7334 uint32 itemcount = m_spellInfo->ReagentCount[i];
7335
7336 // if CastItem is also spell reagent
7337 if (m_CastItem && m_CastItem->GetEntry() == itemid)
7338 {
7339 ItemTemplate const* proto = m_CastItem->GetTemplate();
7340 if (!proto)
7342 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
7343 {
7344 // CastItem will be used up and does not count as reagent
7345 int32 charges = m_CastItem->GetSpellCharges(s);
7346 if (proto->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
7347 {
7348 ++itemcount;
7349 break;
7350 }
7351 }
7352 }
7353 if (!player->HasItemCount(itemid, itemcount))
7354 return SPELL_FAILED_REAGENTS;
7355 }
7356 }
7357
7358 // check totem-item requirements (items presence in inventory)
7359 uint32 totems = 2;
7360 for (int i = 0; i < 2; ++i)
7361 {
7362 if (m_spellInfo->Totem[i] != 0)
7363 {
7364 if (player->HasItemCount(m_spellInfo->Totem[i]))
7365 {
7366 totems -= 1;
7367 continue;
7368 }
7369 }
7370 else
7371 totems -= 1;
7372 }
7373 if (totems != 0)
7374 return SPELL_FAILED_TOTEMS; //0x7C
7375
7376 // Check items for TotemCategory (items presence in inventory)
7378 for (int i = 0; i < 2; ++i)
7379 {
7380 if (m_spellInfo->TotemCategory[i] != 0)
7381 {
7383 {
7384 TotemCategory -= 1;
7385 continue;
7386 }
7387 }
7388 else
7389 TotemCategory -= 1;
7390 }
7391 if (TotemCategory != 0)
7392 return SPELL_FAILED_TOTEM_CATEGORY; //0x7B
7393 }
7394
7395 // special checks for spell effects
7396 for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
7397 {
7398 switch (m_spellInfo->Effects[i].Effect)
7399 {
7402 {
7403 // m_targets.GetUnitTarget() means explicit cast, otherwise we dont check for possible equip error
7404 Unit* target = m_targets.GetUnitTarget() ? m_targets.GetUnitTarget() : player;
7405 if (target->IsPlayer() && !IsTriggered())
7406 {
7407 // SPELL_EFFECT_CREATE_ITEM_2 differs from SPELL_EFFECT_CREATE_ITEM in that it picks the random item to create from a pool of potential items,
7408 // so we need to make sure there is at least one free space in the player's inventory
7410 if (target->ToPlayer()->GetFreeInventorySpace() == 0)
7411 {
7412 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7414 }
7415
7416 if (m_spellInfo->Effects[i].ItemType)
7417 {
7418 ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(m_spellInfo->Effects[i].ItemType);
7419 if (!itemTemplate)
7421
7422 uint32 createCount = std::clamp<uint32>(m_spellInfo->Effects[i].CalcValue(), 1u, itemTemplate->GetMaxStackSize());
7423 ItemPosCountVec dest;
7424 InventoryResult msg = target->ToPlayer()->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, createCount);
7425 if (msg != EQUIP_ERR_OK)
7426 {
7428 if (!itemTemplate->ItemLimitCategory)
7429 {
7430 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7432 }
7433 else
7434 {
7435 // Conjure Food/Water/Refreshment spells
7438 else if (!(target->ToPlayer()->HasItemCount(m_spellInfo->Effects[i].ItemType)))
7439 {
7440 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7442 }
7443 else
7444 player->CastSpell(player, m_spellInfo->Effects[EFFECT_1].CalcValue(), false); // move this to anywhere
7445
7447 }
7448 }
7449 }
7450 }
7451 break;
7452 }
7454 {
7455 if (player->GetFreeInventorySpace() == 0)
7456 {
7457 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7459 }
7460 break;
7461 }
7463 if (m_spellInfo->Effects[i].ItemType && m_targets.GetItemTarget()
7465 {
7466 // cannot enchant vellum for other player
7469 // do not allow to enchant vellum from scroll made by vellum-prevent exploit
7472 ItemPosCountVec dest;
7473 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, 1);
7474 if (msg != EQUIP_ERR_OK)
7475 {
7476 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7478 }
7479 }
7480 [[fallthrough]];
7482 {
7483 Item* targetItem = m_targets.GetItemTarget();
7484 if (!targetItem)
7486
7487 // Apply item level restriction
7489 {
7490 uint32 requiredLevel = targetItem->GetTemplate()->RequiredLevel;
7491 if (!requiredLevel)
7492 requiredLevel = targetItem->GetTemplate()->ItemLevel;
7493
7494 if (requiredLevel < m_spellInfo->BaseLevel)
7495 return SPELL_FAILED_LOWLEVEL;
7496 }
7497
7498 if (m_CastItem && m_spellInfo->MaxLevel > 0 && targetItem->GetTemplate()->ItemLevel > m_spellInfo->MaxLevel)
7500
7501 bool isItemUsable = false;
7502 for (uint8 e = 0; e < MAX_ITEM_PROTO_SPELLS; ++e)
7503 {
7504 ItemTemplate const* proto = targetItem->GetTemplate();
7505 if (proto->Spells[e].SpellId && (
7508 {
7509 isItemUsable = true;
7510 break;
7511 }
7512 }
7513
7514 SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(m_spellInfo->Effects[i].MiscValue);
7515 // do not allow adding usable enchantments to items that have use effect already
7516 if (enchantEntry)
7517 {
7518 for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s)
7519 {
7520 switch (enchantEntry->type[s])
7521 {
7523 if (isItemUsable)
7525 break;
7527 {
7528 uint32 numSockets = 0;
7529 for (uint32 socket = 0; socket < MAX_ITEM_PROTO_SOCKETS; ++socket)
7530 if (targetItem->GetTemplate()->Socket[socket].Color)
7531 ++numSockets;
7532
7533 if (numSockets == MAX_ITEM_PROTO_SOCKETS || targetItem->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT))
7535 break;
7536 }
7537 }
7538 }
7539 }
7540
7541 // Not allow enchant in trade slot for some enchant type
7542 if (targetItem->GetOwner() != m_caster)
7543 {
7544 if (!enchantEntry)
7545 return SPELL_FAILED_ERROR;
7546 if (enchantEntry->slot & ENCHANTMENT_CAN_SOULBOUND)
7548 }
7549 break;
7550 }
7552 {
7553 Item* item = m_targets.GetItemTarget();
7554 if (!item)
7556 // Not allow enchant in trade slot for some enchant type
7557 if (item->GetOwner() != m_caster)
7558 {
7559 uint32 enchant_id = m_spellInfo->Effects[i].MiscValue;
7560 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
7561 if (!pEnchant)
7562 return SPELL_FAILED_ERROR;
7563 if (pEnchant->slot & ENCHANTMENT_CAN_SOULBOUND)
7565 }
7566
7567 // Apply item level restriction
7569 {
7570 uint32 requiredLevel = item->GetTemplate()->RequiredLevel;
7571 if (!requiredLevel)
7572 requiredLevel = item->GetTemplate()->ItemLevel;
7573
7574 if (requiredLevel < m_spellInfo->BaseLevel)
7575 return SPELL_FAILED_LOWLEVEL;
7576 }
7577
7580
7581 break;
7582 }
7584 // check item existence in effect code (not output errors at offhand hold item effect to main hand for example
7585 break;
7587 {
7588 if (!m_targets.GetItemTarget())
7590
7591 // prevent disenchanting in trade slot
7594
7595 ItemTemplate const* itemProto = m_targets.GetItemTarget()->GetTemplate();
7596 if (!itemProto)
7598
7599 uint32 item_quality = itemProto->Quality;
7600 // 2.0.x addon: Check player enchanting level against the item disenchanting requirements
7601 uint32 item_disenchantskilllevel = itemProto->RequiredDisenchantSkill;
7602 if (item_disenchantskilllevel == uint32(-1))
7604 if (item_disenchantskilllevel > player->GetSkillValue(SKILL_ENCHANTING))
7606 if (item_quality > 4 || item_quality < 2)
7608 if (itemProto->Class != ITEM_CLASS_WEAPON && itemProto->Class != ITEM_CLASS_ARMOR)
7610 if (!itemProto->DisenchantID)
7612 break;
7613 }
7615 {
7616 if (!m_targets.GetItemTarget())
7618 //ensure item is a prospectable ore
7621 //prevent prospecting in trade slot
7624 //Check for enough skill in jewelcrafting
7625 uint32 item_prospectingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
7626 if (item_prospectingskilllevel > player->GetSkillValue(SKILL_JEWELCRAFTING))
7628 //make sure the player has the required ores in inventory
7629 if (m_targets.GetItemTarget()->GetCount() < 5)
7631
7634
7635 break;
7636 }
7638 {
7639 if (!m_targets.GetItemTarget())
7641 //ensure item is a millable herb
7644 //prevent milling in trade slot
7647 //Check for enough skill in inscription
7648 uint32 item_millingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
7649 if (item_millingskilllevel > player->GetSkillValue(SKILL_INSCRIPTION))
7651 //make sure the player has the required herbs in inventory
7652 if (m_targets.GetItemTarget()->GetCount() < 5)
7654
7657
7658 break;
7659 }
7662 {
7663 if (!m_caster->IsPlayer())
7665
7667 break;
7668
7670 if (!pItem || pItem->IsBroken())
7672
7673 switch (pItem->GetTemplate()->SubClass)
7674 {
7676 {
7677 uint32 ammo = pItem->GetEntry();
7678 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7679 return SPELL_FAILED_NO_AMMO;
7680 };
7681 break;
7685 {
7687 if (!ammo)
7688 {
7689 // Requires No Ammo
7690 if (m_caster->HasAura(46699))
7691 break; // skip other checks
7692
7693 return SPELL_FAILED_NO_AMMO;
7694 }
7695
7696 ItemTemplate const* ammoProto = sObjectMgr->GetItemTemplate(ammo);
7697 if (!ammoProto)
7698 return SPELL_FAILED_NO_AMMO;
7699
7700 if (ammoProto->Class != ITEM_CLASS_PROJECTILE)
7701 return SPELL_FAILED_NO_AMMO;
7702
7703 // check ammo ws. weapon compatibility
7704 switch (pItem->GetTemplate()->SubClass)
7705 {
7708 if (ammoProto->SubClass != ITEM_SUBCLASS_ARROW)
7709 return SPELL_FAILED_NO_AMMO;
7710 break;
7712 if (ammoProto->SubClass != ITEM_SUBCLASS_BULLET)
7713 return SPELL_FAILED_NO_AMMO;
7714 break;
7715 default:
7716 return SPELL_FAILED_NO_AMMO;
7717 }
7718
7719 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7720 {
7722 return SPELL_FAILED_NO_AMMO;
7723 }
7724 };
7725 break;
7727 break;
7728 default:
7729 break;
7730 }
7731 break;
7732 }
7734 {
7735 uint32 item_id = m_spellInfo->Effects[i].ItemType;
7736 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
7737
7738 if (!pProto)
7740
7741 if (Item* pitem = player->GetItemByEntry(item_id))
7742 {
7743 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
7744 if (pProto->Spells[x].SpellCharges != 0 && pitem->GetSpellCharges(x) == pProto->Spells[x].SpellCharges)
7746 }
7747 break;
7748 }
7749 default:
7750 break;
7751 }
7752 }
7753
7754 // check weapon presence in slots for main/offhand weapons
7755 if (/*never skip those checks !HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT) &&*/ m_spellInfo->EquippedItemClass >= 0)
7756 {
7757 // main hand weapon required
7759 {
7761
7762 // skip spell if no weapon in slot or broken
7763 if (!item || item->IsBroken())
7765
7766 // skip spell if weapon not fit to triggered spell
7769 }
7770
7771 // offhand hand weapon required
7773 {
7775
7776 // skip spell if no weapon in slot or broken
7777 if (!item || item->IsBroken())
7779
7780 // skip spell if weapon not fit to triggered spell
7783 }
7784
7786 }
7787
7788 return SPELL_CAST_OK;
7789}
@ ITEM_ENCHANTMENT_TYPE_USE_SPELL
Definition DBCEnums.h:373
@ ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET
Definition DBCEnums.h:374
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
#define MAX_SPELL_REAGENTS
Definition DBCStructure.h:1640
#define MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS
Definition DBCStructure.h:1839
std::int8_t int8
Definition Define.h:105
@ ITEM_SUBCLASS_WEAPON_CROSSBOW
Definition ItemTemplate.h:362
@ ITEM_SUBCLASS_WEAPON_GUN
Definition ItemTemplate.h:347
@ ITEM_SUBCLASS_WEAPON_BOW
Definition ItemTemplate.h:346
@ ITEM_SUBCLASS_WEAPON_WAND
Definition ItemTemplate.h:363
@ ITEM_SUBCLASS_WEAPON_THROWN
Definition ItemTemplate.h:360
@ ITEM_SPELLTRIGGER_ON_USE
Definition ItemTemplate.h:77
@ ITEM_SPELLTRIGGER_ON_NO_DELAY_USE
Definition ItemTemplate.h:87
@ ITEM_FLAG_IS_MILLABLE
Definition ItemTemplate.h:176
@ ITEM_FLAG_NO_REAGENT_COST
Definition ItemTemplate.h:175
@ ITEM_FLAG_IS_PROSPECTABLE
Definition ItemTemplate.h:165
@ ITEM_SUBCLASS_ARROW
Definition ItemTemplate.h:416
@ ITEM_SUBCLASS_BULLET
Definition ItemTemplate.h:417
#define MAX_ITEM_PROTO_SOCKETS
Definition ItemTemplate.h:614
#define MAX_ITEM_PROTO_SPELLS
Definition ItemTemplate.h:615
@ ITEM_CLASS_PROJECTILE
Definition ItemTemplate.h:297
@ ITEM_CLASS_ARMOR
Definition ItemTemplate.h:295
@ ITEM_CLASS_WEAPON
Definition ItemTemplate.h:293
@ ITEM_CLASS_CONSUMABLE
Definition ItemTemplate.h:291
InventoryResult
Definition Item.h:46
@ EQUIP_ERR_OK
Definition Item.h:47
@ EQUIP_ERR_INVENTORY_FULL
Definition Item.h:97
#define MAX_ITEM_SPELLS
Definition Item.h:215
@ ENCHANTMENT_CAN_SOULBOUND
Definition Item.h:201
@ NULL_BAG
Definition Item.h:40
@ NULL_SLOT
Definition Item.h:41
@ PRISMATIC_ENCHANTMENT_SLOT
Definition Item.h:175
LootStore LootTemplates_Milling("milling_loot_template", "item entry (herb)", true)
LootStore LootTemplates_Prospecting("prospecting_loot_template", "item entry (ore)", true)
std::vector< ItemPosCount > ItemPosCountVec
Definition Player.h:767
@ EFFECT_1
Definition SharedDefines.h:32
@ MAX_POWERS
Definition SharedDefines.h:287
@ SPELL_EFFECT_DISENCHANT
Definition SharedDefines.h:888
@ SPELL_EFFECT_PROSPECTING
Definition SharedDefines.h:916
@ SPELL_EFFECT_ENCHANT_HELD_ITEM
Definition SharedDefines.h:881
@ SPELL_EFFECT_ENCHANT_ITEM
Definition SharedDefines.h:842
@ SPELL_EFFECT_WEAPON_DAMAGE
Definition SharedDefines.h:847
@ SPELL_EFFECT_HEAL
Definition SharedDefines.h:799
@ SPELL_EFFECT_MILLING
Definition SharedDefines.h:947
@ SPELL_EFFECT_CREATE_MANA_GEM
Definition SharedDefines.h:855
@ SPELL_EFFECT_CREATE_ITEM_2
Definition SharedDefines.h:946
@ SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
Definition SharedDefines.h:806
@ SPELL_EFFECT_ENERGIZE
Definition SharedDefines.h:819
@ SPELL_EFFECT_CREATE_RANDOM_ITEM
Definition SharedDefines.h:848
@ SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
Definition SharedDefines.h:945
@ SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
Definition SharedDefines.h:843
@ SPELL_EFFECT_CREATE_ITEM
Definition SharedDefines.h:813
@ SPELL_ATTR2_ALLOW_LOW_LEVEL_BUFF
Definition SharedDefines.h:470
@ SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON
Definition SharedDefines.h:514
@ SPELLFAMILY_MAGE
Definition SharedDefines.h:3797
TotemCategory
Definition SharedDefines.h:3333
@ SPELL_FAILED_CANT_BE_MILLED
Definition SharedDefines.h:976
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND
Definition SharedDefines.h:991
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS
Definition SharedDefines.h:989
@ SPELL_FAILED_ITEM_AT_MAX_CHARGES
Definition SharedDefines.h:1139
@ SPELL_FAILED_TARGET_NOT_PLAYER
Definition SharedDefines.h:1082
@ SPELL_FAILED_ALREADY_AT_FULL_POWER
Definition SharedDefines.h:964
@ SPELL_FAILED_NOT_TRADEABLE
Definition SharedDefines.h:1030
@ SPELL_FAILED_ITEM_NOT_READY
Definition SharedDefines.h:1005
@ SPELL_FAILED_NO_CHARGES_REMAIN
Definition SharedDefines.h:1036
@ SPELL_FAILED_ITEM_GONE
Definition SharedDefines.h:1003
@ SPELL_FAILED_NO_AMMO
Definition SharedDefines.h:1035
@ SPELL_FAILED_ITEM_NOT_FOUND
Definition SharedDefines.h:1004
@ SPELL_FAILED_EQUIPPED_ITEM
Definition SharedDefines.h:988
@ SPELL_FAILED_ALREADY_AT_FULL_HEALTH
Definition SharedDefines.h:962
@ SPELL_FAILED_ON_USE_ENCHANT
Definition SharedDefines.h:1130
@ SPELL_FAILED_TOTEMS
Definition SharedDefines.h:1091
@ SPELL_FAILED_ERROR
Definition SharedDefines.h:992
@ SPELL_FAILED_REAGENTS
Definition SharedDefines.h:1060
@ SPELL_FAILED_MAX_SOCKETS
Definition SharedDefines.h:1144
@ SPELL_FAILED_CANT_BE_DISENCHANTED
Definition SharedDefines.h:974
@ SPELL_FAILED_TOO_MANY_OF_ITEM
Definition SharedDefines.h:1089
@ SPELL_FAILED_NEED_MORE_ITEMS
Definition SharedDefines.h:1015
@ SPELL_FAILED_CANT_BE_PROSPECTED
Definition SharedDefines.h:977
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND
Definition SharedDefines.h:990
@ SPELL_FAILED_TOTEM_CATEGORY
Definition SharedDefines.h:1090
@ SKILL_INSCRIPTION
Definition SharedDefines.h:3252
@ SKILL_ENCHANTING
Definition SharedDefines.h:3204
@ SKILL_JEWELCRAFTING
Definition SharedDefines.h:3235
@ PLAYER_AMMO_ID
Definition UpdateFields.h:369
uint32 GetEnchantmentId(EnchantmentSlot slot) const
Definition Item.h:304
int32 GetSpellCharges(uint8 index=0) const
Definition Item.h:317
bool IsBroken() const
Definition Item.h:257
bool IsWeaponVellum() const
Definition Item.h:338
bool IsArmorVellum() const
Definition Item.h:339
Player * GetOwner() const
Definition Item.cpp:549
ObjectGuid GetOwnerGUID() const
Definition Item.h:231
uint32 GetCount() const
Definition Item.h:272
bool IsFitToSpellRequirements(SpellInfo const *spellInfo) const
Definition Item.cpp:884
bool HaveLootFor(uint32 loot_id) const
Definition LootMgr.h:224
uint32 GetUInt32Value(uint16 index) const
Definition Object.cpp:294
bool HasItemFitToSpellRequirements(SpellInfo const *spellInfo, Item const *ignoreItem=nullptr) const
Definition Player.cpp:12545
uint32 GetFreeInventorySpace() const
Definition PlayerStorage.cpp:466
Item * GetItemByEntry(uint32 entry) const
Definition PlayerStorage.cpp:3362
bool HasItemCount(uint32 item, uint32 count=1, bool inBankAlso=false) const
Definition PlayerStorage.cpp:655
bool HasItemTotemCategory(uint32 TotemCategory) const
Definition PlayerStorage.cpp:851
bool CanNoReagentCast(SpellInfo const *spellInfo) const
Definition Player.cpp:12590
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=nullptr, uint32 itemid=0)
Definition PlayerStorage.cpp:4014
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=nullptr) const
Definition Player.h:1285
uint32 GetItemTargetEntry() const
Definition Spell.h:149
uint32 MaxLevel
Definition SpellInfo.h:359
std::array< int32, MAX_SPELL_REAGENTS > Reagent
Definition SpellInfo.h:374
flag96 SpellFamilyFlags
Definition SpellInfo.h:389
std::array< uint32, 2 > TotemCategory
Definition SpellInfo.h:379
int32 EquippedItemClass
Definition SpellInfo.h:376
std::array< uint32, 2 > Totem
Definition SpellInfo.h:373
std::array< uint32, MAX_SPELL_REAGENTS > ReagentCount
Definition SpellInfo.h:375
ObjectGuid m_castItemGUID
Definition Spell.h:546
bool CanUseAttackType(uint8 attacktype) const
Definition Unit.h:933
bool IsFullHealth() const
Definition Unit.h:1039
uint32 GetMaxPower(Powers power) const
Definition Unit.h:1061
void SetUInt32Value(uint16 index, uint32 value)
Definition Unit.cpp:21182
uint32 GetPower(Powers power) const
Definition Unit.h:1060
Definition ItemTemplate.h:619
uint32 DisenchantID
Definition ItemTemplate.h:690
uint32 Quality
Definition ItemTemplate.h:626
uint32 RequiredSkillRank
Definition ItemTemplate.h:638
uint32 GetMaxStackSize() const
Definition ItemTemplate.h:727
_Spell Spells[MAX_ITEM_PROTO_SPELLS]
Definition ItemTemplate.h:662
uint32 RequiredDisenchantSkill
Definition ItemTemplate.h:684
uint32 RequiredLevel
Definition ItemTemplate.h:636
bool HasFlag(ItemFlags flag) const
Definition ItemTemplate.h:825
uint32 Class
Definition ItemTemplate.h:621
uint32 ItemLimitCategory
Definition ItemTemplate.h:687
uint32 SubClass
Definition ItemTemplate.h:622
_Socket Socket[MAX_ITEM_PROTO_SOCKETS]
Definition ItemTemplate.h:681
Definition DBCStructure.h:1842
uint32 type[MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS]
Definition DBCStructure.h:1845
uint32 slot
Definition DBCStructure.h:1852
uint32 Color
Definition ItemTemplate.h:602
int32 SpellCharges
Definition ItemTemplate.h:593
uint32 SpellTrigger
Definition ItemTemplate.h:592
int32 SpellId
Definition ItemTemplate.h:591

References BASE_ATTACK, Player::CanNoReagentCast(), Player::CanStoreNewItem(), Unit::CanUseAttackType(), Unit::CastSpell(), ItemTemplate::Class, _Socket::Color, ItemTemplate::DisenchantID, SpellInfo::DmgClass, EFFECT_1, SpellInfo::Effects, ENCHANTMENT_CAN_SOULBOUND, EQUIP_ERR_INVENTORY_FULL, EQUIP_ERR_OK, SpellInfo::EquippedItemClass, Item::GetCount(), Item::GetEnchantmentId(), Object::GetEntry(), Player::GetFreeInventorySpace(), Object::GetGUID(), Player::GetItemByEntry(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetItemTargetEntry(), SpellCastTargets::GetItemTargetGUID(), Unit::GetMaxPower(), ItemTemplate::GetMaxStackSize(), Item::GetOwner(), Item::GetOwnerGUID(), Unit::GetPower(), Player::GetSkillValue(), Item::GetSpellCharges(), Item::GetTemplate(), Object::GetUInt32Value(), SpellCastTargets::GetUnitTarget(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), Unit::HasAura(), ItemTemplate::HasFlag(), Player::HasItemCount(), Player::HasItemFitToSpellRequirements(), Player::HasItemTotemCategory(), HasTriggeredCastFlag(), LootStore::HaveLootFor(), Item::IsArmorVellum(), Item::IsBroken(), Item::IsFitToSpellRequirements(), Unit::IsFullHealth(), Object::IsPlayer(), IsTriggered(), Item::IsWeaponVellum(), ITEM_CLASS_ARMOR, ITEM_CLASS_CONSUMABLE, ITEM_CLASS_PROJECTILE, ITEM_CLASS_WEAPON, ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET, ITEM_ENCHANTMENT_TYPE_USE_SPELL, ITEM_FLAG_IS_MILLABLE, ITEM_FLAG_IS_PROSPECTABLE, ITEM_FLAG_NO_REAGENT_COST, ITEM_SPELLTRIGGER_ON_NO_DELAY_USE, ITEM_SPELLTRIGGER_ON_USE, ITEM_SUBCLASS_ARROW, ITEM_SUBCLASS_BULLET, ITEM_SUBCLASS_WEAPON_BOW, ITEM_SUBCLASS_WEAPON_CROSSBOW, ITEM_SUBCLASS_WEAPON_GUN, ITEM_SUBCLASS_WEAPON_THROWN, ITEM_SUBCLASS_WEAPON_WAND, ItemTemplate::ItemLevel, ItemTemplate::ItemLimitCategory, LootTemplates_Milling, LootTemplates_Prospecting, m_attackType, m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, m_weaponItem, MAX_ITEM_PROTO_SOCKETS, MAX_ITEM_PROTO_SPELLS, MAX_ITEM_SPELLS, MAX_POWERS, MAX_SPELL_EFFECTS, MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS, MAX_SPELL_REAGENTS, SpellInfo::MaxLevel, NULL_BAG, NULL_SLOT, OFF_ATTACK, PLAYER_AMMO_ID, PRISMATIC_ENCHANTMENT_SLOT, ItemTemplate::Quality, RANGED_ATTACK, SpellInfo::Reagent, SpellInfo::ReagentCount, ItemTemplate::RequiredDisenchantSkill, ItemTemplate::RequiredLevel, ItemTemplate::RequiredSkillRank, Player::SendEquipError(), Unit::SetUInt32Value(), SKILL_ENCHANTING, SKILL_INSCRIPTION, SKILL_JEWELCRAFTING, SpellItemEnchantmentEntry::slot, sObjectMgr, ItemTemplate::Socket, SPELL_ATTR2_ALLOW_LOW_LEVEL_BUFF, SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON, SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_CREATE_ITEM, SPELL_EFFECT_CREATE_ITEM_2, SPELL_EFFECT_CREATE_MANA_GEM, SPELL_EFFECT_CREATE_RANDOM_ITEM, SPELL_EFFECT_DISENCHANT, SPELL_EFFECT_ENCHANT_HELD_ITEM, SPELL_EFFECT_ENCHANT_ITEM, SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC, SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY, SPELL_EFFECT_ENERGIZE, SPELL_EFFECT_HEAL, SPELL_EFFECT_MILLING, SPELL_EFFECT_PROSPECTING, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_FAILED_ALREADY_AT_FULL_HEALTH, SPELL_FAILED_ALREADY_AT_FULL_POWER, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_CANT_BE_DISENCHANTED, SPELL_FAILED_CANT_BE_MILLED, SPELL_FAILED_CANT_BE_PROSPECTED, SPELL_FAILED_DONT_REPORT, SPELL_FAILED_EQUIPPED_ITEM, SPELL_FAILED_EQUIPPED_ITEM_CLASS, SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND, SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND, SPELL_FAILED_ERROR, SPELL_FAILED_HIGHLEVEL, SPELL_FAILED_ITEM_AT_MAX_CHARGES, SPELL_FAILED_ITEM_GONE, SPELL_FAILED_ITEM_NOT_FOUND, SPELL_FAILED_ITEM_NOT_READY, SPELL_FAILED_LOW_CASTLEVEL, SPELL_FAILED_LOWLEVEL, SPELL_FAILED_MAX_SOCKETS, SPELL_FAILED_NEED_MORE_ITEMS, SPELL_FAILED_NO_AMMO, SPELL_FAILED_NO_CHARGES_REMAIN, SPELL_FAILED_NOT_TRADEABLE, SPELL_FAILED_ON_USE_ENCHANT, SPELL_FAILED_REAGENTS, SPELL_FAILED_TARGET_NOT_PLAYER, SPELL_FAILED_TOO_MANY_OF_ITEM, SPELL_FAILED_TOTEM_CATEGORY, SPELL_FAILED_TOTEMS, _Spell::SpellCharges, SPELLFAMILY_MAGE, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, _Spell::SpellId, ItemTemplate::Spells, _Spell::SpellTrigger, sSpellItemEnchantmentStore, ItemTemplate::SubClass, TARGET_UNIT_PET, Object::ToPlayer(), SpellInfo::Totem, SpellInfo::TotemCategory, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, and SpellItemEnchantmentEntry::type.

Referenced by CheckCast().

◆ CheckPetCast()

SpellCastResult Spell::CheckPetCast ( Unit target)
6845{
6846 if (m_caster->HasUnitState(UNIT_STATE_CASTING) && !HasTriggeredCastFlag(TRIGGERED_IGNORE_CAST_IN_PROGRESS)) //prevent spellcast interruption by another spellcast
6848
6849 // dead owner (pets still alive when owners ressed?)
6850 if (Unit* owner = m_caster->GetCharmerOrOwner())
6851 if (!owner->IsAlive() && m_caster->GetEntry() != 30230) // Rise Ally
6853
6854 if (!target && m_targets.GetUnitTarget())
6855 target = m_targets.GetUnitTarget();
6856
6858 {
6859 if (!target)
6861 m_targets.SetUnitTarget(target);
6862 }
6863
6864 // xinef: Calculate power cost here, so funciton checking power can work properly and dont return bad results
6866
6867 // cooldown
6868 if (Creature const* creatureCaster = m_caster->ToCreature())
6869 if (creatureCaster->HasSpellCooldown(m_spellInfo->Id))
6871
6872 // Check if spell is affected by GCD
6876
6877 return CheckCast(true);
6878}
bool HasGlobalCooldown(SpellInfo const *spellInfo) const
Definition CharmInfo.cpp:397
void SetUnitTarget(Unit *target)
Definition Spell.cpp:239
int32 CalcPowerCost(Unit const *caster, SpellSchoolMask schoolMask, Spell *spell=nullptr) const
Definition SpellInfo.cpp:2408
uint32 StartRecoveryCategory
Definition SpellInfo.h:351

References SpellInfo::CalcPowerCost(), CheckCast(), Unit::GetCharmerOrOwner(), Unit::GetCharmInfo(), Object::GetEntry(), CharmInfo::GetGlobalCooldownMgr(), SpellCastTargets::GetUnitTarget(), GlobalCooldownMgr::HasGlobalCooldown(), HasTriggeredCastFlag(), Unit::HasUnitState(), SpellInfo::Id, m_caster, m_powerCost, m_spellInfo, m_spellSchoolMask, m_targets, SpellInfo::NeedsExplicitUnitTarget(), SpellCastTargets::SetUnitTarget(), SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_CASTER_DEAD, SPELL_FAILED_NOT_READY, SPELL_FAILED_SPELL_IN_PROGRESS, SpellInfo::StartRecoveryCategory, Object::ToCreature(), TRIGGERED_IGNORE_CAST_IN_PROGRESS, and UNIT_STATE_CASTING.

Referenced by CanAutoCast(), WorldSession::HandlePetActionHelper(), and WorldSession::HandlePetCastSpellOpcode().

◆ CheckPower()

SpellCastResult Spell::CheckPower ( )
7164{
7165 // item cast not used power
7166 if (m_CastItem)
7167 return SPELL_CAST_OK;
7168
7169 //While .cheat power is enabled dont check if we need power to cast the spell
7170 if (m_caster->IsPlayer())
7171 {
7173 {
7174 return SPELL_CAST_OK;
7175 }
7176 }
7177
7178 // health as power used - need check health amount
7180 {
7183 return SPELL_CAST_OK;
7184 }
7185 // Check valid power type
7187 {
7188 LOG_ERROR("spells", "Spell::CheckPower: Unknown power type '{}'", m_spellInfo->PowerType);
7189 return SPELL_FAILED_UNKNOWN;
7190 }
7191
7192 //check rune cost only if a spell has PowerType == POWER_RUNE
7194 {
7196 if (failReason != SPELL_CAST_OK)
7197 return failReason;
7198 }
7199
7200 // Check power amount
7203 return SPELL_FAILED_NO_POWER;
7204 else
7205 return SPELL_CAST_OK;
7206}
@ CHEAT_POWER
Definition Player.h:998
@ POWER_HEALTH
Definition SharedDefines.h:289
@ POWER_RUNE
Definition SharedDefines.h:285
@ SPELL_FAILED_NO_POWER
Definition SharedDefines.h:1045
@ SPELL_FAILED_UNKNOWN
Definition SharedDefines.h:1147
PowerType
Definition VehicleDefines.h:29
uint32 RuneCostID
Definition SpellInfo.h:369
uint32 PowerType
Definition SpellInfo.h:363
SpellCastResult CheckRuneCost(uint32 RuneCostID)
Definition Spell.cpp:5438
uint32 GetHealth() const
Definition Unit.h:1033

References CHEAT_POWER, CheckRuneCost(), Player::GetCommandStatus(), Unit::GetHealth(), Unit::GetPower(), Object::IsPlayer(), LOG_ERROR, m_caster, m_CastItem, m_powerCost, m_spellInfo, MAX_POWERS, POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, SPELL_CAST_OK, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_NO_POWER, SPELL_FAILED_UNKNOWN, and Object::ToPlayer().

Referenced by CheckCast().

◆ CheckRange()

SpellCastResult Spell::CheckRange ( bool  strict)
7078{
7079 // Don't check for instant cast spells
7080 if (!strict && m_casttime == 0)
7081 return SPELL_CAST_OK;
7082
7083 uint32 range_type = 0;
7084
7086 {
7087 // check needed by 68766 51693 - both spells are cast on enemies and have 0 max range
7088 // these are triggered by other spells - possibly we should omit range check in that case?
7089 if (m_spellInfo->RangeEntry->ID == 1)
7090 return SPELL_CAST_OK;
7091
7092 range_type = m_spellInfo->RangeEntry->Flags;
7093 }
7094
7095 Unit* target = m_targets.GetUnitTarget();
7096 float max_range = m_caster->GetSpellMaxRangeForTarget(target, m_spellInfo);
7097 float min_range = m_caster->GetSpellMinRangeForTarget(target, m_spellInfo);
7098
7099 // xinef: hack for npc shooters
7100 if (min_range && GetCaster()->IsCreature() && !GetCaster()->GetOwnerGUID().IsPlayer() && min_range <= 6.0f)
7101 range_type = SPELL_RANGE_RANGED;
7102
7103 if (Player* modOwner = m_caster->GetSpellModOwner())
7104 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, max_range, this);
7105
7106 // xinef: dont check max_range to strictly after cast
7107 if (range_type != SPELL_RANGE_MELEE && !strict)
7108 max_range += std::min(3.0f, max_range * 0.1f); // 10% but no more than 3yd
7109
7110 if (target)
7111 {
7112 if (target != m_caster)
7113 {
7114 // Xinef: Spells with 5yd range can hit target 9yd away?
7115 if (range_type == SPELL_RANGE_MELEE)
7116 {
7117 float real_max_range = max_range;
7119 real_max_range -= MIN_MELEE_REACH; // Because of lag, we can not check too strictly here (is only used if both caster and target are moving)
7120 else
7121 real_max_range -= 2 * MIN_MELEE_REACH;
7122
7123 if (!m_caster->IsWithinMeleeRange(target, std::max(real_max_range, 0.0f)))
7125 }
7126 else if (!m_caster->IsWithinCombatRange(target, max_range))
7127 return SPELL_FAILED_OUT_OF_RANGE; //0x5A;
7128
7130 {
7131 if (m_caster->IsWithinMeleeRange(target))
7133 }
7134
7135 if (m_caster->IsPlayer() && (m_spellInfo->FacingCasterFlags & SPELL_FACING_FLAG_INFRONT) && !m_caster->HasInArc(static_cast<float>(M_PI), target) && !m_caster->IsWithinBoundaryRadius(target))
7137 }
7138
7139 // Xinef: check min range for self casts
7140 if (min_range && range_type != SPELL_RANGE_RANGED && m_caster->IsWithinCombatRange(target, min_range)) // skip this check if min_range = 0
7142 }
7143
7144 if (GameObject* goTarget = m_targets.GetGOTarget())
7145 {
7146 if (!goTarget->IsAtInteractDistance(m_caster->ToPlayer(), m_spellInfo))
7147 {
7149 }
7150 }
7151
7152 if (m_targets.HasDst() && !m_targets.HasTraj())
7153 {
7154 if (!m_caster->IsWithinDist3d(m_targets.GetDstPos(), max_range))
7156 if (min_range && m_caster->IsWithinDist3d(m_targets.GetDstPos(), min_range))
7158 }
7159
7160 return SPELL_CAST_OK;
7161}
#define MIN_MELEE_REACH
Definition ObjectDefines.h:46
@ SPELL_FAILED_TOO_CLOSE
Definition SharedDefines.h:1088
@ SPELL_FAILED_OUT_OF_RANGE
Definition SharedDefines.h:1057
@ SPELLMOD_RANGE
Definition SpellDefines.h:81
@ SPELL_FACING_FLAG_INFRONT
Definition SpellDefines.h:128
@ SPELL_RANGE_MELEE
Definition Spell.h:91
@ SPELL_RANGE_RANGED
Definition Spell.h:92
SpellRangeEntry const * RangeEntry
Definition SpellInfo.h:370
uint32 FacingCasterFlags
Definition SpellInfo.h:339
Unit * GetCaster() const
Definition Spell.h:597
bool IsWithinBoundaryRadius(const Unit *obj) const
Definition Unit.cpp:705
bool IsWithinCombatRange(Unit const *obj, float dist2compare) const
Definition Unit.cpp:650
float GetSpellMinRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition Unit.cpp:15268
bool IsWithinMeleeRange(Unit const *obj, float dist=0.f) const
Definition Unit.cpp:666
float GetSpellMaxRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition Unit.cpp:15248
bool HasLeewayMovement() const
Definition Unit.h:1645
bool IsWithinDist3d(float x, float y, float z, float dist) const
Definition Object.cpp:1300
bool HasInArc(float arcangle, const Position *pos, float targetRadius=0.0f) const
Definition Position.cpp:141
uint32 Flags
Definition DBCStructure.h:1798
uint32 ID
Definition DBCStructure.h:1795

References SpellInfo::DmgClass, SpellInfo::FacingCasterFlags, SpellRangeEntry::Flags, GetCaster(), SpellCastTargets::GetDstPos(), SpellCastTargets::GetGOTarget(), Unit::GetSpellMaxRangeForTarget(), Unit::GetSpellMinRangeForTarget(), Unit::GetSpellModOwner(), SpellCastTargets::GetUnitTarget(), SpellCastTargets::HasDst(), Position::HasInArc(), Unit::HasLeewayMovement(), SpellCastTargets::HasTraj(), SpellInfo::Id, SpellRangeEntry::ID, Object::IsCreature(), Object::IsPlayer(), Unit::IsWithinBoundaryRadius(), Unit::IsWithinCombatRange(), WorldObject::IsWithinDist3d(), Unit::IsWithinMeleeRange(), m_caster, m_casttime, m_spellInfo, m_targets, MIN_MELEE_REACH, SpellInfo::RangeEntry, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_RANGED, SPELL_FACING_FLAG_INFRONT, SPELL_FAILED_OUT_OF_RANGE, SPELL_FAILED_TOO_CLOSE, SPELL_FAILED_UNIT_NOT_INFRONT, SPELL_RANGE_MELEE, SPELL_RANGE_RANGED, SPELLMOD_RANGE, and Object::ToPlayer().

Referenced by CheckCast().

◆ CheckRuneCost()

SpellCastResult Spell::CheckRuneCost ( uint32  RuneCostID)
5439{
5440 if (m_spellInfo->PowerType != POWER_RUNE || !RuneCostID)
5441 return SPELL_CAST_OK;
5442
5443 if (!m_caster->IsPlayer())
5444 return SPELL_CAST_OK;
5445
5446 Player* player = m_caster->ToPlayer();
5447 //If we are in .cheat power mode we dont need to check the cost as we are expected to be able to use it anyways (infinite power)
5448 if (player->GetCommandStatus(CHEAT_POWER))
5449 {
5450 return SPELL_CAST_OK;
5451 }
5452
5454 return SPELL_CAST_OK;
5455
5456 SpellRuneCostEntry const* src = sSpellRuneCostStore.LookupEntry(RuneCostID);
5457
5458 if (!src)
5459 return SPELL_CAST_OK;
5460
5461 if (src->NoRuneCost())
5462 return SPELL_CAST_OK;
5463
5464 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5465
5466 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5467 {
5468 runeCost[i] = src->RuneCost[i];
5469 if (Player* modOwner = m_caster->GetSpellModOwner())
5470 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5471 }
5472
5473 runeCost[RUNE_DEATH] = MAX_RUNES; // calculated later
5474
5475 for (uint32 i = 0; i < MAX_RUNES; ++i)
5476 {
5477 RuneType rune = player->GetCurrentRune(i);
5478 if ((player->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0))
5479 runeCost[rune]--;
5480 }
5481
5482 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5483 if (runeCost[i] > 0)
5484 runeCost[RUNE_DEATH] += runeCost[i];
5485
5486 if (runeCost[RUNE_DEATH] > MAX_RUNES)
5487 return SPELL_FAILED_NO_POWER; // not sure if result code is correct
5488
5489 return SPELL_CAST_OK;
5490}
DBCStorage< SpellRuneCostEntry > sSpellRuneCostStore(SpellRuneCostfmt)
RuneType
Definition Player.h:403
@ RUNE_DEATH
Definition Player.h:407
@ NUM_RUNE_TYPES
Definition Player.h:408
#define MAX_RUNES
Definition Player.h:393
@ CLASS_DEATH_KNIGHT
Definition SharedDefines.h:146
@ SPELLMOD_COST
Definition SpellDefines.h:90
@ CLASS_CONTEXT_ABILITY
Definition UnitDefines.h:236
uint32 GetRuneCooldown(uint8 index) const
Definition Player.h:2518
bool IsClass(Classes playerClass, ClassContext context=CLASS_CONTEXT_NONE) const override
Definition Player.cpp:1295
RuneType GetCurrentRune(uint8 index) const
Definition Player.h:2517
Definition DBCStructure.h:1806
uint32 RuneCost[3]
Definition DBCStructure.h:1808
bool NoRuneCost() const
Definition DBCStructure.h:1811

References CHEAT_POWER, CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, Player::GetCommandStatus(), Player::GetCurrentRune(), Player::GetRuneCooldown(), Unit::GetSpellModOwner(), SpellInfo::Id, Player::IsClass(), Object::IsPlayer(), m_caster, m_spellInfo, MAX_RUNES, SpellRuneCostEntry::NoRuneCost(), NUM_RUNE_TYPES, POWER_RUNE, SpellInfo::PowerType, RUNE_DEATH, SpellRuneCostEntry::RuneCost, SPELL_CAST_OK, SPELL_FAILED_NO_POWER, SPELLMOD_COST, sSpellRuneCostStore, and Object::ToPlayer().

Referenced by CheckPower().

◆ CheckScriptEffectImplicitTargets()

bool Spell::CheckScriptEffectImplicitTargets ( uint32  effIndex,
uint32  effIndexToCheck 
)
protected
8767{
8768 // Skip if there are not any script
8769 if (!m_loadedScripts.size())
8770 return true;
8771
8772 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end(); ++itr)
8773 {
8774 std::list<SpellScript::ObjectTargetSelectHandler>::iterator targetSelectHookEnd = (*itr)->OnObjectTargetSelect.end(), targetSelectHookItr = (*itr)->OnObjectTargetSelect.begin();
8775 for (; targetSelectHookItr != targetSelectHookEnd; ++targetSelectHookItr)
8776 if (((*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8777 (!(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8778 return false;
8779
8780 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator areaTargetSelectHookEnd = (*itr)->OnObjectAreaTargetSelect.end(), areaTargetSelectHookItr = (*itr)->OnObjectAreaTargetSelect.begin();
8781 for (; areaTargetSelectHookItr != areaTargetSelectHookEnd; ++areaTargetSelectHookItr)
8782 if (((*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8783 (!(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8784 return false;
8785 }
8786 return true;
8787}

References m_loadedScripts, and m_spellInfo.

Referenced by SelectEffectImplicitTargets().

◆ CheckSpellFocus()

SpellCastResult Spell::CheckSpellFocus ( )
7792{
7793 // check spell focus object
7795 {
7797 Cell cell(p);
7798
7799 GameObject* ok = nullptr;
7802
7804 Map& map = *m_caster->GetMap();
7805 cell.Visit(p, object_checker, map, *m_caster, m_caster->GetVisibilityRange());
7806
7807 if (!ok)
7809
7810 focusObject = ok; // game object found in range
7811 }
7812 return SPELL_CAST_OK;
7813}
@ SPELL_FAILED_REQUIRES_SPELL_FOCUS
Definition SharedDefines.h:1062
Definition GridNotifiers.h:648
Definition Map.h:160
void Visit(const Cell &cell, TypeContainerVisitor< T, CONTAINER > &visitor)
Definition Map.h:681
uint32 RequiresSpellFocus
Definition SpellInfo.h:338
Definition TypeContainerVisitor.h:105
Definition TypeContainer.h:118
CellCoord ComputeCellCoord(float x, float y)
Definition GridDefines.h:197
Definition GridNotifiers.h:310
Definition Cell.h:45

References Acore::ComputeCellCoord(), focusObject, WorldObject::GetMap(), Position::GetPositionX(), Position::GetPositionY(), WorldObject::GetVisibilityRange(), m_caster, m_spellInfo, SpellInfo::RequiresSpellFocus, SPELL_CAST_OK, SPELL_FAILED_REQUIRES_SPELL_FOCUS, and Cell::Visit().

Referenced by CheckCast().

◆ CheckSrc()

void Spell::CheckSrc ( )
inline
bool HasSrc() const
Definition Spell.h:173
void SetSrc(float x, float y, float z)
Definition Spell.cpp:367

References SpellCastTargets::HasSrc(), m_caster, m_targets, and SpellCastTargets::SetSrc().

◆ CleanupTargetList()

void Spell::CleanupTargetList ( )
2374{
2375 m_UniqueTargetInfo.clear();
2376 m_UniqueGOTargetInfo.clear();
2377 m_UniqueItemInfo.clear();
2378 m_delayMoment = 0;
2380}
uint64 m_delayTrajectory
Definition Spell.h:664

References m_delayMoment, m_delayTrajectory, m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

Referenced by spell_dk_raise_dead::CheckCast(), and Spell().

◆ Delayed()

void Spell::Delayed ( )
7816{
7817 if (!m_caster)// || !m_caster->IsPlayer())
7818 return;
7819
7820 //if (m_spellState == SPELL_STATE_DELAYED)
7821 // return; // spell is active and can't be time-backed
7822
7823 if (isDelayableNoMore()) // Spells may only be delayed twice
7824 return;
7825
7827 return;
7828
7829 // spells not loosing casting time (slam, dynamites, bombs..)
7830 //if (!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE))
7831 // return;
7832
7833 //check pushback reduce
7834 int32 delaytime = 500; // spellcasting delay is normally 500ms
7835 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7838 if (delayReduce >= 100)
7839 return;
7840
7841 AddPct(delaytime, -delayReduce);
7842
7843 if (m_timer + delaytime > m_casttime)
7844 {
7845 delaytime = m_casttime - m_timer;
7847 }
7848 else
7849 m_timer += delaytime;
7850
7851 LOG_DEBUG("spells", "Spell {} partially interrupted for ({}) ms at damage", m_spellInfo->Id, delaytime);
7852
7853 WorldPacket data(SMSG_SPELL_DELAYED, 8 + 4);
7854 data << m_caster->GetPackGUID();
7855 data << uint32(delaytime);
7856
7857 m_caster->SendMessageToSet(&data, true);
7858}
#define LOG_DEBUG(filterType__,...)
Definition Log.h:170
@ SPELL_ATTR6_NO_PUSHBACK
Definition SharedDefines.h:630
@ SPELL_AURA_REDUCE_PUSHBACK
Definition SpellAuraDefines.h:212
@ SPELLMOD_NOT_LOSE_CASTING_TIME
Definition SpellDefines.h:85
T AddPct(T &base, U pct)
Definition Util.h:67
PackedGuid const & GetPackGUID() const
Definition Object.h:115
void ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell *spell=nullptr, bool temporaryPet=false)
Definition Player.cpp:9830
bool isDelayableNoMore()
Definition Spell.h:652
int32 GetTotalAuraModifier(AuraType auratype) const
Definition Unit.cpp:6006
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition Object.cpp:2065
Definition WorldPacket.h:26
@ SMSG_SPELL_DELAYED
Definition Opcodes.h:512

References AddPct(), Player::ApplySpellMod(), Object::GetPackGUID(), Unit::GetTotalAuraModifier(), SpellInfo::HasAttribute(), SpellInfo::Id, isDelayableNoMore(), LOG_DEBUG, m_caster, m_casttime, m_spellInfo, m_timer, WorldObject::SendMessageToSet(), SMSG_SPELL_DELAYED, SPELL_ATTR6_NO_PUSHBACK, SPELL_AURA_REDUCE_PUSHBACK, SPELLMOD_NOT_LOSE_CASTING_TIME, and Object::ToPlayer().

◆ DelayedChannel()

void Spell::DelayedChannel ( )
7861{
7863 return;
7864
7865 if (isDelayableNoMore()) // Spells may only be delayed twice
7866 return;
7867
7869 return;
7870
7871 //check pushback reduce
7872 // should be affected by modifiers, not take the dbc duration.
7873 int32 duration = ((m_channeledDuration > 0) ? m_channeledDuration : m_spellInfo->GetDuration());
7874
7875 int32 delaytime = CalculatePct(duration, 25); // channeling delay is normally 25% of its time per hit
7876 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7879 if (delayReduce >= 100)
7880 return;
7881
7882 AddPct(delaytime, -delayReduce);
7883
7884 if (m_timer <= delaytime)
7885 {
7886 delaytime = m_timer;
7887 m_timer = 0;
7888 }
7889 else
7890 m_timer -= delaytime;
7891
7892 LOG_DEBUG("spells.aura", "Spell {} partially interrupted for {} ms, new duration: {} ms", m_spellInfo->Id, delaytime, m_timer);
7893
7894 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7895 if ((*ihit).missCondition == SPELL_MISS_NONE)
7896 if (Unit* unit = (m_caster->GetGUID() == ihit->targetGUID) ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
7897 unit->DelayOwnedAuras(m_spellInfo->Id, m_originalCasterGUID, delaytime);
7898
7899 // partially interrupt persistent area auras
7901 dynObj->Delay(delaytime);
7902
7904}
T CalculatePct(T base, U pct)
Definition Util.h:61
Definition DynamicObject.h:35
uint32 getState() const
Definition Spell.h:505
DynamicObject * GetDynObject(uint32 spellId)
Definition Unit.cpp:6224

References AddPct(), Player::ApplySpellMod(), CalculatePct(), SpellInfo::GetDuration(), Unit::GetDynObject(), Object::GetGUID(), getState(), Unit::GetTotalAuraModifier(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, isDelayableNoMore(), Object::IsPlayer(), LOG_DEBUG, m_caster, m_channeledDuration, m_originalCasterGUID, m_spellInfo, m_timer, m_UniqueTargetInfo, SendChannelUpdate(), SPELL_ATTR6_NO_PUSHBACK, SPELL_AURA_REDUCE_PUSHBACK, SPELL_MISS_NONE, SPELL_STATE_CASTING, SPELLMOD_NOT_LOSE_CASTING_TIME, and Object::ToPlayer().

◆ DoAllEffectOnLaunchTarget()

void Spell::DoAllEffectOnLaunchTarget ( TargetInfo targetInfo,
float *  multiplier 
)
protected
8344{
8345 Unit* unit = nullptr;
8346 // In case spell hit target, do all effect on that target
8347 if (targetInfo.missCondition == SPELL_MISS_NONE)
8348 unit = m_caster->GetGUID() == targetInfo.targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, targetInfo.targetGUID);
8349 // In case spell reflect from target, do all effect on caster (if hit)
8350 else if (targetInfo.missCondition == SPELL_MISS_REFLECT && targetInfo.reflectResult == SPELL_MISS_NONE)
8351 unit = m_caster;
8352 if (!unit)
8353 return;
8354
8355 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8356 {
8357 if (targetInfo.effectMask & (1 << i))
8358 {
8359 m_damage = 0;
8360 m_healing = 0;
8361
8362 HandleEffects(unit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH_TARGET);
8363
8364 if (m_damage > 0)
8365 {
8366 // Xinef: Area Auras, AoE Targetting spells AND Chain Target spells (cleave etc.)
8367 if (m_spellInfo->Effects[i].IsAreaAuraEffect() || m_spellInfo->Effects[i].IsTargetingArea() || (m_spellInfo->Effects[i].ChainTarget > 1 && m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MAGIC))
8368 {
8371 if (m_caster->IsPlayer())
8372 {
8373 uint32 targetAmount = m_UniqueTargetInfo.size();
8374 if (targetAmount > 10)
8375 m_damage = m_damage * 10 / targetAmount;
8376 }
8377 }
8378 }
8379
8380 if (m_applyMultiplierMask & (1 << i))
8381 {
8383 m_damageMultipliers[i] *= multiplier[i];
8384 }
8385 targetInfo.damage += m_damage;
8386 }
8387 }
8388
8389 // xinef: totem's inherit owner crit chance and dancing rune weapon
8390 Unit* caster = m_caster;
8391 if (m_caster->IsTotem() || m_caster->GetEntry() == 27893)
8392 {
8393 if (Unit* owner = m_caster->GetOwner())
8394 caster = owner;
8395 }
8396 else if (m_originalCaster)
8397 caster = m_originalCaster;
8398
8399 float critChance = caster->SpellDoneCritChance(unit, m_spellInfo, m_spellSchoolMask, m_attackType, false);
8400 critChance = unit->SpellTakenCritChance(caster, m_spellInfo, m_spellSchoolMask, critChance, m_attackType, false);
8401 targetInfo.crit = roll_chance_f(std::max(0.0f, critChance));
8402}
bool roll_chance_f(float chance)
Definition Random.h:57
@ SPELL_ATTR7_TREAT_AS_NPC_AOE
Definition SharedDefines.h:678
uint32 SchoolMask
Definition SpellInfo.h:393
float SpellTakenCritChance(Unit const *caster, SpellInfo const *spellProto, SpellSchoolMask schoolMask, float doneChance, WeaponAttackType attackType, bool skipEffectCheck) const
Definition Unit.cpp:12162
float SpellDoneCritChance(Unit const *, SpellInfo const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType, bool skipEffectCheck) const
Definition Unit.cpp:12087
int32 CalculateAOEDamageReduction(int32 damage, uint32 schoolMask, bool npcCaster) const
Definition Unit.cpp:20242

References Unit::CalculateAOEDamageReduction(), TargetInfo::crit, TargetInfo::damage, SpellInfo::DmgClass, TargetInfo::effectMask, SpellInfo::Effects, Object::GetEntry(), Object::GetGUID(), Unit::GetOwner(), GetSpellInfo(), ObjectAccessor::GetUnit(), HandleEffects(), SpellInfo::HasAttribute(), Unit::IsControlledByPlayer(), Object::IsPlayer(), Unit::IsTotem(), m_applyMultiplierMask, m_attackType, m_caster, m_damage, m_damageMultipliers, m_healing, m_originalCaster, m_spellInfo, m_spellSchoolMask, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, TargetInfo::missCondition, TargetInfo::reflectResult, roll_chance_f(), SpellInfo::SchoolMask, SPELL_ATTR7_TREAT_AS_NPC_AOE, SPELL_DAMAGE_CLASS_MAGIC, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_MISS_NONE, SPELL_MISS_REFLECT, Unit::SpellDoneCritChance(), Unit::SpellTakenCritChance(), and TargetInfo::targetGUID.

Referenced by HandleLaunchPhase().

◆ DoAllEffectOnTarget() [1/3]

void Spell::DoAllEffectOnTarget ( GOTargetInfo target)
protected
3348{
3349 if (target->processed) // Check target
3350 return;
3351 target->processed = true; // Target checked in apply effects procedure
3352
3353 uint32 effectMask = target->effectMask;
3354 if (!effectMask)
3355 return;
3356
3357 GameObject* go = m_caster->GetMap()->GetGameObject(target->targetGUID);
3358 if (!go)
3359 return;
3360
3363
3364 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3365 if (effectMask & (1 << effectNumber))
3366 HandleEffects(nullptr, nullptr, go, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3367
3368 // xinef: inform ai about spellhit
3370
3372
3374}
virtual void SpellHit(Unit *, SpellInfo const *)
Definition GameObjectAI.h:66
GameObjectAI * AI() const
Definition GameObject.h:305
void CallScriptBeforeHitHandlers(SpellMissInfo missInfo)
Definition Spell.cpp:8685
void CallScriptOnHitHandlers()
Definition Spell.cpp:8698
void CallScriptAfterHitHandlers()
Definition Spell.cpp:8711

References GameObject::AI(), CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), Spell::GOTargetInfo::effectMask, Map::GetGameObject(), WorldObject::GetMap(), HandleEffects(), m_caster, m_spellInfo, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), Spell::GOTargetInfo::processed, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_MISS_NONE, GameObjectAI::SpellHit(), and Spell::GOTargetInfo::targetGUID.

◆ DoAllEffectOnTarget() [2/3]

void Spell::DoAllEffectOnTarget ( ItemTargetInfo target)
protected
3377{
3378 uint32 effectMask = target->effectMask;
3379 if (!target->item || !effectMask)
3380 return;
3381
3384
3385 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3386 if (effectMask & (1 << effectNumber))
3387 HandleEffects(nullptr, target->item, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3388
3390
3392}

References CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), Spell::ItemTargetInfo::effectMask, HandleEffects(), Spell::ItemTargetInfo::item, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), SPELL_EFFECT_HANDLE_HIT_TARGET, and SPELL_MISS_NONE.

◆ DoAllEffectOnTarget() [3/3]

void Spell::DoAllEffectOnTarget ( TargetInfo target)
protected
Todo:
: check how broad this rule should be
2612{
2613 if (!target || target->processed)
2614 return;
2615
2616 target->processed = true; // Target checked in apply effects procedure
2617
2618 // Get mask of effects for target
2619 uint8 mask = target->effectMask;
2620
2621 Unit* effectUnit = m_caster->GetGUID() == target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target->targetGUID);
2622 if (!effectUnit && !target->targetGUID.IsPlayer()) // only players may be targeted across maps
2623 return;
2624
2625 if (!effectUnit || m_spellInfo->Id == 45927)
2626 {
2627 uint8 farMask = 0;
2628 // create far target mask
2629 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2630 if (m_spellInfo->Effects[i].IsFarUnitTargetEffect())
2631 if ((1 << i) & mask)
2632 farMask |= (1 << i);
2633
2634 if (!farMask)
2635 return;
2636 // find unit in world
2637 // Xinef: FindUnit Access without Map check!!! Intended
2638 effectUnit = ObjectAccessor::FindPlayer(target->targetGUID);
2639 if (!effectUnit)
2640 return;
2641
2642 // do far effects on the unit
2643 // can't use default call because of threading, do stuff as fast as possible
2644 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2645 if (farMask & (1 << i))
2646 HandleEffects(effectUnit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_HIT_TARGET);
2647 return;
2648 }
2649
2650 if (effectUnit->IsAlive() != target->alive)
2651 return;
2652
2653 // Xinef: absorb delayed projectiles for 500ms
2655 (GameTime::GetGameTimeMS().count() - target->timeDelay) <= effectUnit->m_lastSanctuaryTime && GameTime::GetGameTimeMS().count() < (effectUnit->m_lastSanctuaryTime + 500) &&
2656 effectUnit->FindMap() && !effectUnit->FindMap()->IsDungeon()
2657 )
2658 return; // No missinfo in that case
2659
2660 // Get original caster (if exist) and calculate damage/healing from him data
2662
2663 // Skip if m_originalCaster not avaiable
2664 if (!caster)
2665 return;
2666
2667 SpellMissInfo missInfo = target->missCondition;
2668
2669 // Need init unitTarget by default unit (can changed in code on reflect)
2670 // Or on missInfo != SPELL_MISS_NONE unitTarget undefined (but need in trigger subsystem)
2671 unitTarget = effectUnit;
2672
2673 // Reset damage/healing counter
2674 m_damage = target->damage;
2675 m_healing = -target->damage;
2676
2677 m_spellAura = nullptr; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied
2678
2681
2682 //Spells with this flag cannot trigger if effect is casted on self
2684 bool reflectedSpell = missInfo == SPELL_MISS_REFLECT;
2685 Unit* spellHitTarget = nullptr;
2686
2687 if (missInfo == SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
2688 spellHitTarget = unitTarget;
2689 else if (missInfo == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit)
2690 {
2691 missInfo = target->reflectResult;
2692 if (missInfo == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him
2693 {
2694 spellHitTarget = m_caster;
2696 if (m_caster->IsCreature())
2698 }
2699 }
2700
2701 if (spellHitTarget)
2702 {
2703 SpellMissInfo missInfo2 = DoSpellHitOnUnit(spellHitTarget, mask, target->scaleAura);
2704 if (missInfo2 != SPELL_MISS_NONE)
2705 {
2706 if (missInfo2 != SPELL_MISS_MISS)
2707 m_caster->SendSpellMiss(spellHitTarget, m_spellInfo->Id, missInfo2);
2708 m_damage = 0;
2709 spellHitTarget = nullptr;
2710
2711 // Xinef: if missInfo2 is MISS_EVADE, override base missinfo data
2712 if (missInfo2 == SPELL_MISS_EVADE)
2713 missInfo = SPELL_MISS_EVADE;
2714 }
2715 }
2716
2717 // Do not take combo points on dodge and miss
2718 if (missInfo != SPELL_MISS_NONE && m_needComboPoints && m_targets.GetUnitTargetGUID() == target->targetGUID)
2719 {
2720 m_needComboPoints = false;
2721 // Restore spell mods for a miss/dodge/parry Cold Blood
2723 if (m_caster->IsPlayer() && (missInfo == SPELL_MISS_MISS || missInfo == SPELL_MISS_DODGE || missInfo == SPELL_MISS_PARRY))
2724 m_caster->ToPlayer()->RestoreSpellMods(this, 14177);
2725 }
2726
2727 // Fill base trigger info
2728 uint32 procAttacker = m_procAttacker;
2729 uint32 procVictim = m_procVictim;
2730 uint32 procEx = m_procEx;
2731
2732 // Trigger info was not filled in spell::preparedatafortriggersystem - we do it now
2733 if (canEffectTrigger && !procAttacker && !procVictim)
2734 {
2735 bool positive = true;
2736 if (m_damage > 0)
2737 positive = false;
2738 else if (!m_healing)
2739 {
2740 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2741 // If at least one effect negative spell is negative hit
2742 // Xinef: if missInfo is immune state check all effects to properly determine positiveness of spell
2743 if ((missInfo == SPELL_MISS_IMMUNE2 || (mask & (1 << i))) && !m_spellInfo->IsPositiveEffect(i))
2744 {
2745 positive = false;
2746 break;
2747 }
2748 }
2749 switch (m_spellInfo->DmgClass)
2750 {
2752 if (positive)
2753 {
2756 }
2757 else
2758 {
2761 }
2762 break;
2764 if (positive)
2765 {
2768 }
2769 else
2770 {
2773 }
2774 break;
2775 }
2776 }
2778
2779 // All calculated do it!
2780 // Do healing and triggers
2781 if (m_healing > 0)
2782 {
2783 bool crit = target->crit;
2784 uint32 addhealth = m_healing;
2785
2786 if (crit)
2787 {
2788 procEx |= PROC_EX_CRITICAL_HIT;
2789 addhealth = Unit::SpellCriticalHealingBonus(caster, m_spellInfo, addhealth, nullptr);
2790 }
2791 else
2792 procEx |= PROC_EX_NORMAL_HIT;
2793
2794 HealInfo healInfo(caster, unitTarget, addhealth, m_spellInfo, m_spellInfo->GetSchoolMask());
2795
2796 // Xinef: override with forced crit, only visual result
2797 if (GetSpellValue()->ForcedCritResult)
2798 {
2799 crit = true;
2800 procEx |= PROC_EX_CRITICAL_HIT;
2801 }
2802
2803 int32 gain = caster->HealBySpell(healInfo, crit);
2804 float threat = float(gain) * 0.5f;
2805 if (caster->IsClass(CLASS_PALADIN))
2806 threat *= 0.5f;
2807
2809 m_healing = gain;
2810
2811 // Xinef: if heal acutally healed something, add no overheal flag
2812 if (m_healing)
2813 procEx |= PROC_EX_NO_OVERHEAL;
2814
2815 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2816 if (canEffectTrigger)
2817 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2818 m_triggeredByAuraSpell.effectIndex, this, nullptr, &healInfo);
2819 }
2820 // Do damage and triggers
2821 else if (m_damage > 0)
2822 {
2824
2825 // Fill base damage struct (unitTarget - is real spell target)
2827
2828 // Add bonuses and fill damageInfo struct
2829 // Dancing Rune Weapon...
2830 if (m_caster->GetEntry() == 27893)
2831 {
2832 if (Unit* owner = m_caster->GetOwner())
2833 owner->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2834 }
2835 else
2836 caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2837
2838 // xinef: override miss info after absorb / block calculations
2839 if (missInfo == SPELL_MISS_NONE && damageInfo.damage == 0)
2840 {
2841 //if (damageInfo.absorb > 0)
2842 // missInfo = SPELL_MISS_ABSORB;
2843 if (damageInfo.blocked)
2844 missInfo = SPELL_MISS_BLOCK;
2845 }
2846
2847 // Xinef: override with forced crit, only visual result
2848 if (GetSpellValue()->ForcedCritResult)
2849 {
2850 damageInfo.HitInfo |= SPELL_HIT_TYPE_CRIT;
2851 }
2852
2853 Unit::DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
2854
2855 // xinef: health leech handling
2857 {
2858 uint8 effIndex = EFFECT_0;
2859 for (; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2860 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_HEALTH_LEECH)
2861 break;
2862
2863 float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
2864
2865 // get max possible damage, don't count overkill for heal
2866 uint32 healthGain = uint32(-unitTarget->GetHealthGain(-int32(damageInfo.damage)) * healMultiplier);
2867
2868 if (m_caster->IsAlive())
2869 {
2870 healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL, effIndex);
2871 healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
2872
2873 HealInfo healInfo(m_caster, m_caster, healthGain, m_spellInfo, m_spellInfo->GetSchoolMask());
2874 m_caster->HealBySpell(healInfo);
2875 }
2876 }
2877
2878 // Send log damage message to client
2879 caster->SendSpellNonMeleeDamageLog(&damageInfo);
2880 // Xinef: send info to target about reflect
2881 if (reflectedSpell)
2882 effectUnit->SendSpellNonMeleeReflectLog(&damageInfo, effectUnit);
2883
2884 procEx |= createProcExtendMask(&damageInfo, missInfo);
2885 procVictim |= PROC_FLAG_TAKEN_DAMAGE;
2886
2887 caster->DealSpellDamage(&damageInfo, true, this);
2888
2889 // do procs after damage, eg healing effects
2890 // no need to check if target is alive, done in procdamageandspell
2891
2892 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2893 if (canEffectTrigger)
2894 {
2895 DamageInfo dmgInfo(damageInfo, SPELL_DIRECT_DAMAGE);
2896 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2897 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2898
2901 caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, procEx);
2902 }
2903
2904 m_damage = damageInfo.damage;
2905 }
2906 // Passive spell hits/misses or active spells only misses (only triggers)
2907 else
2908 {
2909 // Fill base damage struct (unitTarget - is real spell target)
2911 procEx |= createProcExtendMask(&damageInfo, missInfo);
2912 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2913 if (canEffectTrigger)
2914 {
2915 DamageInfo dmgInfo(damageInfo, NODAMAGE);
2916 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, 0, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2917 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2918
2919 // Xinef: eg. rogue poisons can proc off cheap shot, etc. so this block should be here also
2920 // Xinef: ofc count only spells that HIT the target, little hack used to fool the system
2924 }
2925
2926 // Failed Pickpocket, reveal rogue
2928 {
2932 }
2933 }
2934
2935 if (m_caster)
2936 {
2938 {
2941
2942 // Patch 3.0.8: All player spells which cause a creature to become aggressive to you will now also immediately cause the creature to be tapped.
2943 if (effectUnit->IsInCombatWith(m_caster))
2944 {
2945 if (Creature* creature = effectUnit->ToCreature())
2946 {
2947 if (!creature->hasLootRecipient() && m_caster->IsPlayer())
2948 {
2949 creature->SetLootRecipient(m_caster);
2950 }
2951 }
2952 }
2953
2954 // Unsure if there are more spells that are not supposed to stop enemy from
2955 // regenerating HP from food, so for now it stays as an ID.
2956 const uint32 SPELL_PREMEDITATION = 14183;
2957 if (m_spellInfo->Id != SPELL_PREMEDITATION)
2958 {
2959 if (!effectUnit->IsStandState())
2960 {
2962 }
2963 }
2964 }
2965 }
2966
2967 if (missInfo != SPELL_MISS_EVADE && effectUnit != m_caster && m_caster->IsFriendlyTo(effectUnit) && m_spellInfo->IsPositive() &&
2969 {
2970 m_caster->SetInCombatWith(effectUnit);
2971 }
2972
2973 // Check for SPELL_ATTR7_CAN_CAUSE_INTERRUPT
2975 caster->CastSpell(effectUnit, SPELL_INTERRUPT_NONPLAYER, true);
2976
2977 if (spellHitTarget)
2978 {
2979 //AI functions
2980 if (spellHitTarget->IsCreature())
2981 {
2982 if (spellHitTarget->ToCreature()->IsAIEnabled)
2983 spellHitTarget->ToCreature()->AI()->SpellHit(m_caster, m_spellInfo);
2984 }
2985
2987 m_caster->ToCreature()->AI()->SpellHitTarget(spellHitTarget, m_spellInfo);
2988
2989 // Needs to be called after dealing damage/healing to not remove breaking on damage auras
2990 DoTriggersOnSpellHit(spellHitTarget, mask);
2991
2992 // if target is fallged for pvp also flag caster if a player
2993 // xinef: do not flag spells with aura bind sight (no special attribute)
2994 if (effectUnit->IsPvP() && effectUnit != m_caster && effectUnit->GetOwnerGUID() != m_caster->GetGUID() &&
2996 {
2997 m_caster->ToPlayer()->UpdatePvP(true);
2998 }
2999
3001 }
3002}
@ SPELL_EFFECT_HEALTH_LEECH
Definition SharedDefines.h:798
@ SPELL_ATTR1_NO_THREAT
Definition SharedDefines.h:440
@ SPELL_ATTR3_SUPPRESS_CASTER_PROCS
Definition SharedDefines.h:520
@ CLASS_PALADIN
Definition SharedDefines.h:142
@ SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT
Definition SharedDefines.h:413
@ SPELL_HIT_TYPE_CRIT
Definition SharedDefines.h:1547
SpellMissInfo
Definition SharedDefines.h:1529
@ SPELL_MISS_DODGE
Definition SharedDefines.h:1533
@ SPELL_MISS_IMMUNE2
Definition SharedDefines.h:1538
@ SPELL_MISS_RESIST
Definition SharedDefines.h:1532
@ SPELL_MISS_MISS
Definition SharedDefines.h:1531
@ SPELL_MISS_BLOCK
Definition SharedDefines.h:1535
@ SPELL_ATTR4_SUPPRESS_WEAPON_PROCS
Definition SharedDefines.h:564
@ AURA_INTERRUPT_FLAG_TALK
Definition SpellDefines.h:53
@ SPELL_ATTR0_CU_NO_PVP_FLAG
Definition SpellInfo.h:184
@ SPELL_ATTR0_CU_PICKPOCKET
Definition SpellInfo.h:187
@ PROC_EX_NO_OVERHEAL
Definition SpellMgr.h:213
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG
Definition SpellMgr.h:132
@ PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG
Definition SpellMgr.h:126
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS
Definition SpellMgr.h:129
@ PROC_FLAG_TAKEN_DAMAGE
Definition SpellMgr.h:137
@ PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS
Definition SpellMgr.h:123
static const uint32 SPELL_INTERRUPT_NONPLAYER
Definition Spell.h:277
@ UNIT_STAND_STATE_STAND
Definition UnitDefines.h:32
uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missCondition)
Definition Unit.cpp:16081
@ NODAMAGE
Definition Unit.h:253
@ SPELL_DIRECT_DAMAGE
Definition Unit.h:250
@ HEAL
Definition Unit.h:252
virtual void SpellHitTarget(Unit *, SpellInfo const *)
Definition CreatureAI.h:148
virtual void SpellHit(Unit *, SpellInfo const *)
Definition CreatureAI.h:145
void LowerPlayerDamageReq(uint32 unDamage, bool damagedByPlayer=true)
Definition Creature.cpp:3832
CreatureAI * AI() const
Definition Creature.h:141
Definition Unit.h:331
Definition Unit.h:374
void threatAssist(Unit *victim, float baseThreat, SpellInfo const *threatSpell=nullptr)
Definition HostileRefMgr.cpp:35
void RestoreSpellMods(Spell *spell, uint32 ownerAuraId=0, Aura *aura=nullptr)
Definition Player.cpp:9972
void CastItemCombatSpell(Unit *target, WeaponAttackType attType, uint32 procVictim, uint32 procEx)
Definition Player.cpp:7271
void UpdatePvP(bool state, bool _override=false)
Definition PlayerUpdates.cpp:1530
ObjectGuid GetUnitTargetGUID() const
Definition Spell.cpp:216
uint32 AttributesEx3
Definition SpellInfo.h:328
bool IsAuraEffectEqual(SpellInfo const *otherSpellInfo) const
Definition SpellInfo.cpp:1693
bool IsTargetingArea() const
Definition SpellInfo.cpp:1020
bool IsPositiveEffect(uint8 effIndex) const
Definition SpellInfo.cpp:1237
bool CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const *triggeredByAura=nullptr) const
Definition Spell.cpp:8789
SpellValue const * GetSpellValue()
Definition Spell.h:607
SpellMissInfo DoSpellHitOnUnit(Unit *unit, uint32 effectMask, bool scaleAura)
Definition Spell.cpp:3004
void DoTriggersOnSpellHit(Unit *unit, uint8 effMask)
Definition Spell.cpp:3270
virtual void AttackStart(Unit *)
Definition UnitAI.cpp:27
uint32 m_lastSanctuaryTime
Definition Unit.h:2009
void DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss, Spell const *spell=nullptr)
Definition Unit.cpp:1470
void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo)
Definition Unit.cpp:6541
void SendSpellNonMeleeReflectLog(SpellNonMeleeDamage *log, Unit *attacker)
Definition Unit.cpp:6374
bool CanProc()
Definition Unit.h:1478
bool IsPvP() const
Definition Unit.h:985
uint32 SpellHealingBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition Unit.cpp:12545
void SetInCombatWith(Unit *enemy, uint32 duration=0)
Definition Unit.cpp:13675
int32 HealBySpell(HealInfo &healInfo, bool critical=false)
Definition Unit.cpp:11336
bool IsStandState() const
Definition Unit.cpp:16803
bool IsInCombatWith(Unit const *who) const
Definition Unit.cpp:20898
HostileRefMgr & getHostileRefMgr()
Definition Unit.h:904
int32 GetHealthGain(int32 dVal)
Definition Unit.cpp:14224
static uint32 SpellCriticalHealingBonus(Unit const *caster, SpellInfo const *spellProto, uint32 damage, Unit const *victim)
Definition Unit.cpp:12414
void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log)
Definition Unit.cpp:6406
bool IsAIEnabled
Definition Unit.h:2015
void SetLastDamagedTargetGuid(ObjectGuid const &guid)
Definition Unit.h:913
uint32 SpellHealingBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack=1)
Definition Unit.cpp:12663
void SetStandState(uint8 state)
Definition Unit.cpp:16809
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0, bool isAutoshot=false)
Definition Unit.cpp:5246
static void DealDamageMods(Unit const *victim, uint32 &damage, uint32 *absorb)
Definition Unit.cpp:815
void CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellInfo const *spellInfo, WeaponAttackType attackType=BASE_ATTACK, bool crit=false)
Definition Unit.cpp:1327
Milliseconds GetGameTimeMS()
Definition GameTime.cpp:43
Definition Unit.h:490

References SpellNonMeleeDamage::absorb, Creature::AI(), TargetInfo::alive, UnitAI::AttackStart(), SpellInfo::AttributesEx3, AURA_INTERRUPT_FLAG_TALK, SpellNonMeleeDamage::blocked, Unit::CalculateSpellDamageTaken(), CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), CanExecuteTriggersOnHit(), Unit::CanProc(), Player::CastItemCombatSpell(), Unit::CastSpell(), CLASS_PALADIN, Unit::CombatStart(), createProcExtendMask(), TargetInfo::crit, SpellNonMeleeDamage::damage, TargetInfo::damage, Unit::DealDamageMods(), Unit::DealSpellDamage(), SpellInfo::DmgClass, DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EFFECT_0, TriggeredByAuraSpellData::effectIndex, TargetInfo::effectMask, SpellInfo::Effects, WorldObject::FindMap(), ObjectAccessor::FindPlayer(), Object::GetEntry(), GameTime::GetGameTimeMS(), Object::GetGUID(), Unit::GetHealthGain(), Unit::getHostileRefMgr(), Unit::GetOwner(), Unit::GetOwnerGUID(), SpellInfo::GetSchoolMask(), GetSpellValue(), getState(), ObjectAccessor::GetUnit(), SpellCastTargets::GetUnitTargetGUID(), HandleEffects(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), HEAL, Unit::HealBySpell(), SpellNonMeleeDamage::HitInfo, SpellInfo::Id, Unit::IsAIEnabled, Unit::IsAlive(), SpellInfo::IsAuraEffectEqual(), Unit::IsClass(), Object::IsCreature(), Map::IsDungeon(), Unit::IsFriendlyTo(), Unit::IsInCombat(), Unit::IsInCombatWith(), Object::IsPlayer(), ObjectGuid::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsPositiveEffect(), Unit::IsPvP(), Unit::IsStandState(), SpellInfo::IsTargetingArea(), Creature::LowerPlayerDamageReq(), m_attackType, m_caster, m_damage, m_healing, Unit::m_lastSanctuaryTime, m_needComboPoints, m_originalCaster, m_procAttacker, m_procEx, m_procVictim, m_spellAura, m_spellInfo, m_spellSchoolMask, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, TargetInfo::missCondition, NODAMAGE, PrepareScriptHitHandlers(), PROC_EX_CRITICAL_HIT, PROC_EX_NO_OVERHEAL, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_TAKEN_DAMAGE, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS, Unit::ProcDamageAndSpell(), TargetInfo::processed, TargetInfo::reflectResult, Unit::RemoveAurasWithInterruptFlags(), Player::RestoreSpellMods(), TargetInfo::scaleAura, Unit::SendSpellMiss(), Unit::SendSpellNonMeleeDamageLog(), Unit::SendSpellNonMeleeReflectLog(), Unit::SetInCombatWith(), Unit::SetLastDamagedTargetGuid(), Unit::SetStandState(), SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_ATTR0_CU_NO_PVP_FLAG, SPELL_ATTR0_CU_PICKPOCKET, SPELL_ATTR1_NO_THREAT, SPELL_ATTR3_SUPPRESS_CASTER_PROCS, SPELL_ATTR3_SUPPRESS_TARGET_PROCS, SPELL_ATTR4_SUPPRESS_WEAPON_PROCS, SPELL_ATTR7_CAN_CAUSE_INTERRUPT, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_NONE, SPELL_DAMAGE_CLASS_RANGED, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_DISPEL, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_HEALTH_LEECH, SPELL_HIT_TYPE_CRIT, SPELL_INTERRUPT_NONPLAYER, SPELL_MISS_BLOCK, SPELL_MISS_DODGE, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE2, SPELL_MISS_MISS, SPELL_MISS_NONE, SPELL_MISS_PARRY, SPELL_MISS_REFLECT, SPELL_MISS_RESIST, SPELL_STATE_DELAYED, Unit::SpellCriticalHealingBonus(), Unit::SpellHealingBonusDone(), Unit::SpellHealingBonusTaken(), CreatureAI::SpellHit(), CreatureAI::SpellHitTarget(), TriggeredByAuraSpellData::spellInfo, SpellNonMeleeDamage::target, TargetInfo::targetGUID, HostileRefMgr::threatAssist(), TargetInfo::timeDelay, Object::ToCreature(), Object::ToPlayer(), UNIT_STAND_STATE_STAND, unitTarget, and Player::UpdatePvP().

Referenced by _handle_immediate_phase(), handle_delayed(), and handle_immediate().

◆ DoCreateItem()

void Spell::DoCreateItem ( uint8  effIndex,
uint32  itemId 
)
1648{
1649 if (!unitTarget)
1650 return;
1651
1652 Player* player = unitTarget->ToPlayer();
1653 if (!player)
1654 {
1655 return;
1656 }
1657
1658 uint32 newitemid = itemId;
1659
1660 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(newitemid);
1661 if (!pProto)
1662 {
1663 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1664 return;
1665 }
1666
1667 uint32 addNumber = damage;
1668
1669 // bg reward have some special in code work
1670 bool SelfCast = true;
1671 switch (m_spellInfo->Id)
1672 {
1677 case SPELL_WS_MARK_TIE:
1680 SelfCast = true;
1681 break;
1683 if (player->HasAura(55629 /*SPELL_LIEUTENANT*/))
1684 addNumber = 3;
1685 else if (player->HasAura(33280 /*SPELL_CORPORAL*/))
1686 addNumber = 2;
1687 else
1688 addNumber = 1;
1689 SelfCast = true;
1690 break;
1691 }
1692
1693 if (addNumber < 1)
1694 addNumber = 1;
1695 if (addNumber > pProto->GetMaxStackSize())
1696 addNumber = pProto->GetMaxStackSize();
1697
1698 /* == gem perfection handling == */
1699
1700 // the chance of getting a perfect result
1701 float perfectCreateChance = 0.0f;
1702
1703 // the resulting perfect item if successful
1704 uint32 perfectItemType = itemId;
1705
1706 // get perfection capability and chance
1707 if (CanCreatePerfectItem(player, m_spellInfo->Id, perfectCreateChance, perfectItemType))
1708 if (roll_chance_f(perfectCreateChance)) // if the roll succeeds...
1709 newitemid = perfectItemType; // the perfect item replaces the regular one
1710
1711 /* == gem perfection handling over == */
1712
1713 /* == profession specialization handling == */
1714
1715 // init items_count to 1, since 1 item will be created regardless of specialization
1716 int32 itemsCount = 1;
1717 float additionalCreateChance = 0.0f;
1718 int32 additionalMaxNum = 0;
1719 // get the chance and maximum number for creating extra items
1720 if (canCreateExtraItems(player, m_spellInfo->Id, additionalCreateChance, additionalMaxNum))
1721 {
1722 // roll with this chance till we roll not to create or we create the max num
1723 while (roll_chance_f(additionalCreateChance) && itemsCount <= additionalMaxNum)
1724 ++itemsCount;
1725 }
1726
1727 // really will be created more items
1728 addNumber *= itemsCount;
1729
1730 /* == profession specialization handling over == */
1731
1732 // can the player store the new item?
1733 ItemPosCountVec dest;
1734 uint32 no_space = 0;
1735 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, newitemid, addNumber, &no_space);
1736 if (msg != EQUIP_ERR_OK)
1737 {
1738 // convert to possible store amount
1740 addNumber -= no_space;
1741 else
1742 {
1743 // if not created by another reason from full inventory or unique items amount limitation
1744 player->SendEquipError(msg, nullptr, nullptr, newitemid);
1745 return;
1746 }
1747 }
1748
1749 if (addNumber)
1750 {
1751 // create the new item and store it
1752 Item* pItem = player->StoreNewItem(dest, newitemid, true);
1753
1754 // was it successful? return error if not
1755 if (!pItem)
1756 {
1757 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1758 return;
1759 }
1760
1761 // set the "Crafted by ..." property of the item
1762 if (m_caster->IsPlayer() && pItem->GetTemplate()->HasSignature())
1763 pItem->SetGuidValue(ITEM_FIELD_CREATOR, player->GetGUID());
1764
1765 // send info to the client
1766 player->SendNewItem(pItem, addNumber, true, SelfCast);
1767
1768 sScriptMgr->OnPlayerCreateItem(player, pItem, addNumber);
1769
1770 // we succeeded in creating at least one item, so a levelup is possible
1771 if (SelfCast)
1773 }
1774}
@ SPELL_WS_MARK_WINNER
Definition Battleground.h:97
@ SPELL_AV_MARK_LOSER
Definition Battleground.h:101
@ SPELL_WS_MARK_TIE
Definition Battleground.h:98
@ SPELL_WS_MARK_LOSER
Definition Battleground.h:96
@ SPELL_AB_MARK_LOSER
Definition Battleground.h:99
@ SPELL_WG_MARK_WINNER
Definition Battleground.h:105
@ SPELL_AB_MARK_WINNER
Definition Battleground.h:100
@ SPELL_AV_MARK_WINNER
Definition Battleground.h:102
@ EQUIP_ERR_ITEM_NOT_FOUND
Definition Item.h:70
@ EQUIP_ERR_CANT_CARRY_MORE_OF_THIS
Definition Item.h:64
bool canCreateExtraItems(Player *player, uint32 spellId, float &additionalChance, int32 &newMaxOrEntry)
Definition SkillExtraItems.cpp:226
bool CanCreatePerfectItem(Player *player, uint32 spellId, float &perfectCreateChance, uint32 &perfectItemType)
Definition SkillExtraItems.cpp:202
@ ITEM_FIELD_CREATOR
Definition UpdateFields.h:37
void SetGuidValue(uint16 index, ObjectGuid value)
Definition Object.cpp:712
bool UpdateCraftSkill(uint32 spellid)
Definition PlayerUpdates.cpp:824
void SendNewItem(Item *item, uint32 count, bool received, bool created, bool broadcast=false, bool sendChatMessage=true)
Definition PlayerStorage.cpp:4750
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0)
Definition PlayerStorage.cpp:2524
bool HasSignature() const
Definition ItemTemplate.h:697

References canCreateExtraItems(), CanCreatePerfectItem(), Player::CanStoreNewItem(), damage, EQUIP_ERR_CANT_CARRY_MORE_OF_THIS, EQUIP_ERR_INVENTORY_FULL, EQUIP_ERR_ITEM_NOT_FOUND, EQUIP_ERR_OK, Object::GetGUID(), ItemTemplate::GetMaxStackSize(), Item::GetTemplate(), Unit::HasAura(), ItemTemplate::HasSignature(), SpellInfo::Id, Object::IsPlayer(), ITEM_FIELD_CREATOR, m_caster, m_spellInfo, NULL_BAG, NULL_SLOT, roll_chance_f(), Player::SendEquipError(), Player::SendNewItem(), Object::SetGuidValue(), sObjectMgr, SPELL_AB_MARK_LOSER, SPELL_AB_MARK_WINNER, SPELL_AV_MARK_LOSER, SPELL_AV_MARK_WINNER, SPELL_WG_MARK_WINNER, SPELL_WS_MARK_LOSER, SPELL_WS_MARK_TIE, SPELL_WS_MARK_WINNER, sScriptMgr, Player::StoreNewItem(), Object::ToPlayer(), unitTarget, and Player::UpdateCraftSkill().

Referenced by SpellScript::CreateItem(), EffectCreateItem(), EffectCreateItem2(), and EffectEnchantItemPerm().

◆ DoSpellHitOnUnit()

SpellMissInfo Spell::DoSpellHitOnUnit ( Unit unit,
uint32  effectMask,
bool  scaleAura 
)
protected
Todo:
: this cause soul transfer bugged
3005{
3006 if (!unit || !effectMask)
3007 return SPELL_MISS_EVADE;
3008
3009 // For delayed spells immunity may be applied between missile launch and hit - check immunity for that case
3010 if (m_spellInfo->Speed && ((m_damage > 0 && unit->IsImmunedToDamage(this)) || unit->IsImmunedToSchool(this) || unit->IsImmunedToSpell(m_spellInfo, this)))
3011 {
3012 return SPELL_MISS_IMMUNE;
3013 }
3014
3015 // disable effects to which unit is immune
3016 SpellMissInfo returnVal = SPELL_MISS_IMMUNE;
3017 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3018 {
3019 if (effectMask & (1 << effectNumber))
3020 {
3021 if (unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber))
3022 effectMask &= ~(1 << effectNumber);
3023 // Xinef: Buggs out polymorph
3024 // Xinef: And this is checked in MagicSpellHitResult, why we check resistance twice?
3025 // Xinef: And why we check every spell effect basing on rand and generic dispel info? some effects will be appliend and some wont?
3026 /*else if (m_spellInfo->Effects[effectNumber].IsAura() && !m_spellInfo->IsPositiveEffect(effectNumber))
3027 {
3028 int32 debuff_resist_chance = unit->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
3029 debuff_resist_chance += unit->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
3030
3031 if (debuff_resist_chance > 0)
3032 if (irand(0,10000) <= (debuff_resist_chance * 100))
3033 {
3034 effectMask &= ~(1 << effectNumber);
3035 returnVal = SPELL_MISS_RESIST;
3036 }
3037 }*/
3038 }
3039 }
3040 if (!effectMask)
3041 return returnVal;
3042
3043 if (unit->IsPlayer())
3044 {
3048 }
3049
3050 if (m_caster->IsPlayer())
3051 {
3054 }
3055
3056 if (m_caster != unit)
3057 {
3058 // Recheck UNIT_FLAG_NON_ATTACKABLE for delayed spells
3059 // Xinef: Also check evade state
3060 if (m_spellInfo->Speed > 0.0f)
3061 {
3062 if (unit->IsCreature() && unit->ToCreature()->IsInEvadeMode())
3063 return SPELL_MISS_EVADE;
3064
3066 return SPELL_MISS_EVADE;
3067 }
3068
3069 if (m_caster->_IsValidAttackTarget(unit, m_spellInfo) && /*Intervene Trigger*/ m_spellInfo->Id != 59667)
3070 {
3072 }
3073 else if (m_caster->IsFriendlyTo(unit))
3074 {
3075 // for delayed spells ignore negative spells (after duel end) for friendly targets
3077 if (!IsTriggered() && m_spellInfo->Speed > 0.0f && unit->IsPlayer() && !m_spellInfo->IsPositive())
3078 return SPELL_MISS_EVADE;
3079
3080 // assisting case, healing and resurrection
3082 {
3085 m_caster->ToPlayer()->UpdatePvP(true);
3086 }
3087
3088 // xinef: triggered spells should not prolong combat
3090 {
3091 m_caster->SetInCombatState(unit->GetCombatTimer() > 0, unit);
3092 unit->getHostileRefMgr().threatAssist(m_caster, 0.0f);
3093 }
3094 }
3095 }
3096
3097 uint8 aura_effmask = 0;
3098 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3099 if (effectMask & (1 << i) && m_spellInfo->Effects[i].IsUnitOwnedAuraEffect())
3100 aura_effmask |= 1 << i;
3101
3102 Unit* originalCaster = GetOriginalCaster();
3103 if (!originalCaster)
3104 originalCaster = m_caster;
3105
3106 // Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add
3107 // Xinef: Do not increase diminishing level for self cast
3109 // xinef: do not increase diminish level for bosses (eg. Void Reaver silence is never diminished)
3110 if (((m_spellFlags & SPELL_FLAG_REFLECTED) && !(unit->HasReflectSpellsAura())) || (aura_effmask && m_diminishGroup && unit != m_caster && (!m_caster->IsCreature() || !m_caster->ToCreature()->isWorldBoss())))
3111 {
3114
3115 uint32 flagsExtra = unit->IsCreature() ? unit->ToCreature()->GetCreatureTemplate()->flags_extra : 0;
3116
3117 // Increase Diminishing on unit, current informations for actually casts will use values above
3118 if ((type == DRTYPE_PLAYER && (unit->IsCharmedOwnedByPlayerOrPlayer() || flagsExtra & CREATURE_FLAG_EXTRA_ALL_DIMINISH ||
3120 {
3121 // Do not apply diminish return if caster is NPC
3123 {
3125 }
3126 }
3127 }
3128
3130 {
3132 }
3133
3134 if (aura_effmask)
3135 {
3136 // Select rank for aura with level requirements only in specific cases
3137 // Unit has to be target only of aura effect, both caster and target have to be players, target has to be other than unit target
3138 SpellInfo const* aurSpellInfo = m_spellInfo;
3139 int32 basePoints[3];
3140 if (scaleAura)
3141 {
3143 ASSERT(aurSpellInfo);
3144 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3145 {
3146 basePoints[i] = aurSpellInfo->Effects[i].BasePoints;
3147 if (m_spellInfo->Effects[i].Effect != aurSpellInfo->Effects[i].Effect)
3148 {
3149 aurSpellInfo = m_spellInfo;
3150 break;
3151 }
3152 }
3153 }
3154
3155 if (m_originalCaster)
3156 {
3157 bool refresh = false;
3159 m_spellAura = Aura::TryRefreshStackOrCreate(aurSpellInfo, effectMask, unit, m_originalCaster,
3160 (aurSpellInfo == m_spellInfo) ? &m_spellValue->EffectBasePoints[0] : &basePoints[0], m_CastItem, ObjectGuid::Empty, &refresh, refreshPeriodic);
3161
3162 // xinef: if aura was not refreshed, add proc ex
3163 if (!refresh)
3165
3166 if (m_spellAura)
3167 {
3168 // Prevent aura application if target is banished and immuned
3171 {
3173 return SPELL_MISS_IMMUNE;
3174 }
3175
3176 // Set aura stack amount to desired value
3178 {
3179 if (!refresh)
3181 else
3183 }
3184
3185 // Now Reduce spell duration using data received at spell hit
3186 int32 duration = m_spellAura->GetMaxDuration();
3187 int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup, aurSpellInfo);
3188
3189 // Xinef: if unit == caster - test versus original unit if available
3190 float diminishMod = 1.0f;
3191 if (unit == m_caster && m_targets.GetUnitTarget())
3193 else
3194 diminishMod = unit->ApplyDiminishingToDuration(m_diminishGroup, duration, m_originalCaster, m_diminishLevel, limitduration);
3195
3196 // unit is immune to aura if it was diminished to 0 duration
3197 if (diminishMod == 0.0f)
3198 {
3201 return SPELL_MISS_IMMUNE;
3202 bool found = false;
3203 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3204 if (effectMask & (1 << i) && m_spellInfo->Effects[i].Effect != SPELL_EFFECT_APPLY_AURA)
3205 found = true;
3206 if (!found)
3207 return SPELL_MISS_IMMUNE;
3208 }
3209 else
3210 {
3211 ((UnitAura*)m_spellAura)->SetDiminishGroup(m_diminishGroup);
3212
3213 bool positive = m_spellAura->GetSpellInfo()->IsPositive();
3215 positive = aurApp->IsPositive();
3216
3217 duration = m_originalCaster->ModSpellDuration(aurSpellInfo, unit, duration, positive, effectMask);
3218
3219 // xinef: haste affects duration of those spells twice
3222
3223 if (m_spellValue->AuraDuration != 0)
3224 {
3225 if (m_spellAura->GetMaxDuration() != -1)
3226 {
3228 }
3229
3231 }
3232 else if (duration != m_spellAura->GetMaxDuration())
3233 {
3234 m_spellAura->SetMaxDuration(duration);
3235 m_spellAura->SetDuration(duration);
3236 }
3237
3238 // xinef: apply relic cooldown, imo best place to add this
3241
3244 }
3245 }
3246 }
3247 }
3248
3249 int8 sanct_effect = -1;
3250
3251 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3252 {
3253 // handle sanctuary effects after aura apply!
3254 if (m_spellInfo->Effects[effectNumber].Effect == SPELL_EFFECT_SANCTUARY)
3255 {
3256 sanct_effect = effectNumber;
3257 continue;
3258 }
3259
3260 if (effectMask & (1 << effectNumber))
3261 HandleEffects(unit, nullptr, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3262 }
3263
3264 if (sanct_effect >= 0 && (effectMask & (1 << sanct_effect)))
3265 HandleEffects(unit, nullptr, nullptr, sanct_effect, SPELL_EFFECT_HANDLE_HIT_TARGET);
3266
3267 return SPELL_MISS_NONE;
3268}
@ CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS
Definition CreatureData.h:64
@ CREATURE_FLAG_EXTRA_ALL_DIMINISH
Definition CreatureData.h:65
@ ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER
Definition DBCEnums.h:112
@ ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET
Definition DBCEnums.h:113
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2
Definition DBCEnums.h:181
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET
Definition DBCEnums.h:142
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2
Definition DBCEnums.h:217
@ DIMINISHING_TAUNT
Definition SharedDefines.h:3526
@ SPELL_EFFECT_SANCTUARY
Definition SharedDefines.h:868
@ SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC
Definition SharedDefines.h:591
DiminishingReturnsType
Definition SharedDefines.h:3499
@ DRTYPE_PLAYER
Definition SharedDefines.h:3501
@ DRTYPE_ALL
Definition SharedDefines.h:3502
@ SPELL_AURA_PERIODIC_HASTE
Definition SpellAuraDefines.h:379
@ SPELL_AURA_MOD_STEALTH
Definition SpellAuraDefines.h:79
@ AURA_INTERRUPT_FLAG_HITBYSPELL
Definition SpellDefines.h:43
@ TRIGGERED_NO_PERIODIC_RESET
Will ignore equipped item requirements.
Definition SpellDefines.h:152
@ SPELL_ATTR0_CU_DONT_BREAK_STEALTH
Definition SpellInfo.h:183
int32 GetDiminishingReturnsLimitDuration(DiminishingGroup group, SpellInfo const *spellproto)
Definition SpellMgr.cpp:275
DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const *spellproto, bool triggered)
Definition SpellMgr.cpp:58
DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group)
Definition SpellMgr.cpp:245
@ PROC_EX_NO_AURA_REFRESH
Definition SpellMgr.h:214
@ UNIT_STATE_ATTACK_PLAYER
Definition UnitDefines.h:184
@ UNIT_STATE_ISOLATED
Definition UnitDefines.h:183
@ UNIT_FLAG_NON_ATTACKABLE
Definition UnitDefines.h:253
@ UNIT_MOD_CAST_SPEED
Definition UpdateFields.h:137
Definition SpellAuras.h:37
int32 GetMaxDuration() const
Definition SpellAuras.h:129
void SetStackAmount(uint8 num)
Definition SpellAuras.cpp:995
void SetTriggeredByAuraSpellInfo(SpellInfo const *triggeredByAuraSpellInfo)
Definition SpellAuras.cpp:2747
void _RegisterForTargets()
Definition SpellAuras.h:121
bool ModStackAmount(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT, bool periodicReset=false)
Definition SpellAuras.cpp:1021
static Aura * TryRefreshStackOrCreate(SpellInfo const *spellproto, uint8 tryEffMask, WorldObject *owner, Unit *caster, int32 *baseAmount=nullptr, Item *castItem=nullptr, ObjectGuid casterGUID=ObjectGuid::Empty, bool *refresh=nullptr, bool periodicReset=false)
Definition SpellAuras.cpp:326
void SetDuration(int32 duration, bool withMods=false)
Definition SpellAuras.cpp:868
const AuraApplication * GetApplicationOfTarget(ObjectGuid guid) const
Definition SpellAuras.h:183
void SetMaxDuration(int32 duration)
Definition SpellAuras.h:130
virtual void Remove(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)=0
bool isWorldBoss() const
Definition Creature.h:121
bool IsInEvadeMode() const
Definition Creature.h:135
float GetFloatValue(uint16 index) const
Definition Object.cpp:306
SpellInfo const * GetAuraRankForLevel(uint8 level) const
Definition SpellInfo.cpp:2533
Unit * GetOriginalCaster() const
Definition Spell.h:598
Definition SpellAuras.h:279
bool HasAuraTypeWithAffectMask(AuraType auratype, SpellInfo const *affectedSpell) const
Definition Unit.cpp:5826
DiminishingLevels GetDiminishing(DiminishingGroup group)
Definition Unit.cpp:15108
void IncrDiminishing(DiminishingGroup group)
Definition Unit.cpp:15134
uint32 GetCombatTimer() const
Definition Unit.h:891
bool IsImmunedToSchool(SpellSchoolMask meleeSchoolMask) const
Definition Unit.cpp:12926
void SetContestedPvP(Player *attackedPlayer=nullptr, bool lookForNearContestedGuards=true)
Definition Unit.cpp:17331
bool HasUnitFlag(UnitFlags flags) const
Definition Unit.h:702
float ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration, Unit *caster, DiminishingLevels Level, int32 limitduration)
Definition Unit.cpp:15148
int32 ModSpellDuration(SpellInfo const *spellProto, Unit const *target, int32 duration, bool positive, uint32 effectMask)
Definition Unit.cpp:14974
virtual void AddSpellCooldown(uint32, uint32, uint32, bool needSendToClient=false, bool forceSendToSpectator=false)
Definition Unit.h:1266
void SetInCombatState(bool PvP, Unit *enemy=nullptr, uint32 duration=0)
Definition Unit.cpp:13833
bool HasReflectSpellsAura() const
Definition Unit.h:1733
bool IsCharmedOwnedByPlayerOrPlayer() const
Definition Unit.h:1238
bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask) const
Definition Unit.cpp:12841
virtual bool IsImmunedToSpell(SpellInfo const *spellInfo, Spell const *spell=nullptr)
Definition Unit.cpp:13010
bool IsImmunedToDamageOrSchool(SpellSchoolMask meleeSchoolMask) const
Definition Unit.cpp:12995
bool IsHostileTo(Unit const *unit) const
Definition Unit.cpp:10306
bool _IsValidAttackTarget(Unit const *target, SpellInfo const *bySpell, WorldObject const *obj=nullptr) const
Definition Unit.cpp:13978
ObjectGuid GetCharmerOrOwnerGUID() const
Definition Unit.h:1224
uint32 flags_extra
Definition CreatureData.h:246
int32 AuraDuration
Definition Spell.h:226
uint8 AuraStackAmount
Definition Spell.h:225

References Unit::_IsValidAttackTarget(), Aura::_RegisterForTargets(), ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER, ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, Unit::AddSpellCooldown(), Unit::ApplyDiminishingToDuration(), ASSERT, AURA_INTERRUPT_FLAG_HITBYSPELL, SpellValue::AuraDuration, SpellValue::AuraStackAmount, CREATURE_FLAG_EXTRA_ALL_DIMINISH, CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS, DIMINISHING_TAUNT, DRTYPE_ALL, DRTYPE_PLAYER, SpellValue::EffectBasePoints, SpellInfo::Effects, ObjectGuid::Empty, CreatureTemplate::flags_extra, Aura::GetApplicationOfTarget(), SpellInfo::GetAuraRankForLevel(), Unit::GetCharmerOrOwnerGUID(), Unit::GetCombatTimer(), Creature::GetCreatureTemplate(), Unit::GetDiminishing(), GetDiminishingReturnsGroupForSpell(), GetDiminishingReturnsGroupType(), GetDiminishingReturnsLimitDuration(), Object::GetEntry(), Object::GetFloatValue(), Object::GetGUID(), Unit::getHostileRefMgr(), Unit::GetLevel(), Aura::GetMaxDuration(), GetOriginalCaster(), Aura::GetSpellInfo(), Item::GetTemplate(), SpellCastTargets::GetUnitTarget(), HandleEffects(), SpellInfo::HasAttribute(), Unit::HasAuraTypeWithAffectMask(), Unit::HasReflectSpellsAura(), HasTriggeredCastFlag(), Unit::HasUnitFlag(), Unit::HasUnitState(), SpellInfo::Id, Unit::IncrDiminishing(), ItemTemplate::InventoryType, INVTYPE_RELIC, Unit::IsCharmedOwnedByPlayerOrPlayer(), Object::IsCreature(), Unit::IsFriendlyTo(), Unit::IsHostileTo(), Unit::IsImmunedToDamage(), Unit::IsImmunedToDamageOrSchool(), Unit::IsImmunedToSchool(), Unit::IsImmunedToSpell(), Unit::IsImmunedToSpellEffect(), Unit::IsInCombat(), Creature::IsInEvadeMode(), Object::IsPlayer(), SpellInfo::IsPositive(), IsTriggered(), Creature::isWorldBoss(), m_caster, m_CastItem, m_damage, m_diminishGroup, m_diminishLevel, m_originalCaster, m_procEx, m_spellAura, m_spellFlags, m_spellInfo, m_spellValue, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, Unit::ModSpellDuration(), Aura::ModStackAmount(), PROC_EX_NO_AURA_REFRESH, Aura::Remove(), Unit::RemoveAurasByType(), Unit::RemoveAurasWithInterruptFlags(), Unit::SetContestedPvP(), Aura::SetDuration(), Unit::SetInCombatState(), Aura::SetMaxDuration(), Aura::SetStackAmount(), Aura::SetTriggeredByAuraSpellInfo(), SpellInfo::Speed, SPELL_ATTR0_CU_DONT_BREAK_STEALTH, SPELL_ATTR0_CU_NO_PVP_FLAG, SPELL_ATTR3_SUPPRESS_TARGET_PROCS, SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC, SPELL_AURA_MOD_STEALTH, SPELL_AURA_PERIODIC_HASTE, SPELL_EFFECT_APPLY_AURA, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_SANCTUARY, SPELL_FLAG_REFLECTED, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE, SPELL_MISS_NONE, SPELL_RELIC_COOLDOWN, TriggeredByAuraSpellData::spellInfo, SpellInfo::StackAmount, Player::StartTimedAchievement(), HostileRefMgr::threatAssist(), Object::ToCreature(), Object::ToPlayer(), TRIGGERED_NO_PERIODIC_RESET, Aura::TryRefreshStackOrCreate(), UNIT_FLAG_NON_ATTACKABLE, UNIT_MOD_CAST_SPEED, UNIT_STATE_ATTACK_PLAYER, UNIT_STATE_ISOLATED, unitTarget, Player::UpdateAchievementCriteria(), and Player::UpdatePvP().

Referenced by DoAllEffectOnTarget().

◆ DoTriggersOnSpellHit()

void Spell::DoTriggersOnSpellHit ( Unit unit,
uint8  effMask 
)
protected
Todo:
: move this code to scripts
Todo:
: remove/cleanup this, as this table is not documented and people are doing stupid things with it
3271{
3272 // Apply additional spell effects to target
3274 if (m_preCastSpell)
3275 {
3276 // Paladin immunity shields
3277 if (m_preCastSpell == 61988)
3278 {
3279 // Cast Forbearance
3280 m_caster->CastSpell(unit, 25771, true);
3281 // Cast Avenging Wrath Marker
3282 unit->CastSpell(unit, 61987, true);
3283 }
3284
3285 // Avenging Wrath
3286 if (m_preCastSpell == 61987)
3287 // Cast the serverside immunity shield marker
3288 m_caster->CastSpell(unit, 61988, true);
3289
3290 // Fearie Fire (Feral) - damage
3291 if (m_preCastSpell == 60089)
3292 m_caster->CastSpell(unit, m_preCastSpell, true);
3293 else if (sSpellMgr->GetSpellInfo(m_preCastSpell))
3294 // Blizz seems to just apply aura without bothering to cast
3296 }
3297
3298 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras
3299 // this is executed after spell proc spells on target hit
3300 // spells are triggered for each hit spell target
3301 // info confirmed with retail sniffs of permafrost and shadow weaving
3302 if (!m_hitTriggerSpells.empty())
3303 {
3304 int _duration = 0;
3305 for (HitTriggerSpellList::const_iterator i = m_hitTriggerSpells.begin(); i != m_hitTriggerSpells.end(); ++i)
3306 {
3307 if (CanExecuteTriggersOnHit(effMask, i->triggeredByAura) && roll_chance_i(i->chance))
3308 {
3309 m_caster->CastSpell(unit, i->triggeredSpell->Id, true);
3310 LOG_DEBUG("spells.aura", "Spell {} triggered spell {} by SPELL_AURA_ADD_TARGET_TRIGGER aura", m_spellInfo->Id, i->triggeredSpell->Id);
3311
3312 // SPELL_AURA_ADD_TARGET_TRIGGER auras shouldn't trigger auras without duration
3313 // set duration of current aura to the triggered spell
3314 if (i->triggeredSpell->GetDuration() == -1)
3315 {
3316 if (Aura* triggeredAur = unit->GetAura(i->triggeredSpell->Id, m_caster->GetGUID()))
3317 {
3318 // get duration from aura-only once
3319 if (!_duration)
3320 {
3321 Aura* aur = unit->GetAura(m_spellInfo->Id, m_caster->GetGUID());
3322 _duration = aur ? aur->GetDuration() : -1;
3323 }
3324 triggeredAur->SetDuration(_duration);
3325 }
3326 }
3327 }
3328 }
3329 }
3330
3331 // trigger linked auras remove/apply
3333 if (std::vector<int32> const* spellTriggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id + SPELL_LINK_HIT))
3334 {
3335 for (std::vector<int32>::const_iterator i = spellTriggered->begin(); i != spellTriggered->end(); ++i)
3336 if (*i < 0)
3337 {
3338 unit->RemoveAurasDueToSpell(-(*i));
3339 }
3340 else
3341 {
3342 unit->CastSpell(unit, *i, true, 0, 0, m_caster->GetGUID());
3343 }
3344 }
3345}
bool roll_chance_i(int chance)
Definition Random.h:63
@ SPELL_LINK_HIT
Definition SpellMgr.h:97
int32 GetDuration() const
Definition SpellAuras.h:133
HitTriggerSpellList m_hitTriggerSpells
Definition Spell.h:778
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:5646
Aura * AddAura(uint32 spellId, Unit *target)
Definition Unit.cpp:18960

References Unit::AddAura(), CanExecuteTriggersOnHit(), Unit::CastSpell(), Unit::GetAura(), Aura::GetDuration(), Object::GetGUID(), SpellInfo::Id, LOG_DEBUG, m_caster, m_hitTriggerSpells, m_preCastSpell, m_spellInfo, Unit::RemoveAurasDueToSpell(), roll_chance_i(), SPELL_LINK_HIT, and sSpellMgr.

Referenced by DoAllEffectOnTarget().

◆ EffectActivateObject()

void Spell::EffectActivateObject ( SpellEffIndex  effIndex)
4245{
4247 return;
4248
4249 if (!gameObjTarget)
4250 return;
4251
4252 GameObjectActions action = GameObjectActions(m_spellInfo->Effects[effIndex].MiscValue);
4253 switch (action)
4254 {
4260 break;
4261 case GameObjectActions::Disturb: // What's the difference with Open?
4263 if (Unit* unitCaster = m_caster->ToUnit())
4264 gameObjTarget->Use(unitCaster);
4265 break;
4267 if (Unit* unitCaster = m_caster->ToUnit())
4268 gameObjTarget->UseDoorOrButton(0, false, unitCaster);
4269 [[fallthrough]];
4273 break;
4277 break;
4280 break;
4284 break;
4288 break;
4290 if (Unit* unitCaster = m_caster->ToUnit())
4291 gameObjTarget->UseDoorOrButton(0, true, unitCaster);
4292 break;
4297 {
4298 GameObjectTemplateAddon const* templateAddon = gameObjTarget->GetTemplateAddon();
4299
4300 uint32 artKitIndex = uint32(action) - uint32(GameObjectActions::UseArtKit0);
4301
4302 uint32 artKitValue = 0;
4303 if (templateAddon)
4304 artKitValue = templateAddon->artKits[artKitIndex];
4305
4306 if (artKitValue == 0)
4307 LOG_ERROR("sql.sql", "GameObject {} hit by spell {} needs `artkit{}` in `gameobject_template_addon`", gameObjTarget->GetEntry(), m_spellInfo->Id, artKitIndex);
4308 else
4309 gameObjTarget->SetGoArtKit(artKitValue);
4310
4311 break;
4312 }
4314 LOG_FATAL("spell", "Spell {} has action type NONE in effect {}", m_spellInfo->Id, int32(effIndex));
4315 break;
4316 default:
4317 LOG_ERROR("spell", "Spell {} has unhandled action {} in effect {}", m_spellInfo->Id, int32(action), int32(effIndex));
4318 break;
4319 }
4320}
GameObjectActions
Definition GameObject.h:76
#define LOG_FATAL(filterType__,...)
Definition Log.h:154
@ GO_FLAG_NOT_SELECTABLE
Definition SharedDefines.h:1618
@ GO_FLAG_LOCKED
Definition SharedDefines.h:1615
@ GAMEOBJECT_FLAGS
Definition UpdateFields.h:399
void UseDoorOrButton(uint32 time_to_restore=0, bool alternative=false, Unit *user=nullptr)
Definition GameObject.cpp:1410
void SetGoArtKit(uint8 artkit)
Definition GameObject.cpp:1424
void SendCustomAnim(uint32 anim)
Definition GameObject.cpp:2131
void ResetDoorOrButton()
Definition GameObject.cpp:1400
void DespawnOrUnsummon(Milliseconds delay=0ms, Seconds forcedRespawnTime=0s)
Definition GameObject.cpp:932
GameObjectTemplateAddon const * GetTemplateAddon() const
Definition GameObject.cpp:911
void Use(Unit *user)
Definition GameObject.cpp:1460
void SetFlag(uint16 index, uint32 newFlag)
Definition Object.cpp:834
void ApplyModFlag(uint16 index, uint32 flag, bool apply)
Definition Object.cpp:888
Definition GameObjectData.h:666
std::array< uint32, 4 > artKits
Definition GameObjectData.h:672

References AnimateCustom0, AnimateCustom1, AnimateCustom2, AnimateCustom3, Object::ApplyModFlag(), GameObjectTemplateAddon::artKits, Close, CloseAndLock, Despawn, GameObject::DespawnOrUnsummon(), Destroy, Disturb, effectHandleMode, SpellInfo::Effects, GAMEOBJECT_FLAGS, gameObjTarget, Object::GetEntry(), GameObject::GetTemplateAddon(), GO_FLAG_LOCKED, GO_FLAG_NOT_SELECTABLE, SpellInfo::Id, Lock, LOG_ERROR, LOG_FATAL, m_caster, m_spellInfo, MakeActive, MakeInert, None, Open, OpenAndUnlock, Rebuild, GameObject::ResetDoorOrButton(), GameObject::SendCustomAnim(), Object::SetFlag(), GameObject::SetGoArtKit(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToUnit(), Unlock, GameObject::Use(), UseArtKit0, UseArtKit1, UseArtKit2, UseArtKit3, and GameObject::UseDoorOrButton().

◆ EffectActivateRune()

void Spell::EffectActivateRune ( SpellEffIndex  effIndex)
5763{
5765 return;
5766
5767 if (!m_caster->IsPlayer())
5768 return;
5769
5770 Player* player = m_caster->ToPlayer();
5771
5773 return;
5774
5775 // needed later
5777
5778 uint32 count = damage;
5779 if (count == 0) count = 1;
5780 for (uint32 j = 0; j < MAX_RUNES && count > 0; ++j)
5781 {
5782 if (player->GetRuneCooldown(j) && player->GetCurrentRune(j) == RuneType(m_spellInfo->Effects[effIndex].MiscValue))
5783 {
5784 if (m_spellInfo->Id == 45529)
5785 if (player->GetBaseRune(j) != RuneType(m_spellInfo->Effects[effIndex].MiscValueB))
5786 continue;
5787 player->SetRuneCooldown(j, 0);
5788 player->SetGracePeriod(j, player->IsInCombat()); // xinef: reset grace period
5789 --count;
5790 }
5791 }
5792
5793 // Blood Tap
5794 if (m_spellInfo->Id == 45529 && count > 0)
5795 {
5796 for (uint32 l = 0; l < MAX_RUNES && count > 0; ++l)
5797 {
5798 // Check if both runes are on cd as that is the only time when this needs to come into effect
5799 if ((player->GetRuneCooldown(l) && player->GetCurrentRune(l) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)) && (player->GetRuneCooldown(l + 1) && player->GetCurrentRune(l + 1) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)))
5800 {
5801 // Should always update the rune with the lowest cd
5802 if (player->GetRuneCooldown(l) >= player->GetRuneCooldown(l + 1))
5803 l++;
5804 player->SetRuneCooldown(l, 0);
5805 player->SetGracePeriod(l, player->IsInCombat()); // xinef: reset grace period
5806 --count;
5807 }
5808 else
5809 break;
5810 }
5811 }
5812
5813 // Empower rune weapon
5814 if (m_spellInfo->Id == 47568)
5815 {
5816 // Need to do this just once
5817 if (effIndex != 0)
5818 return;
5819
5820 for (uint32 i = 0; i < MAX_RUNES; ++i)
5821 {
5822 if (player->GetRuneCooldown(i) && (player->GetCurrentRune(i) == RUNE_FROST || player->GetCurrentRune(i) == RUNE_DEATH))
5823 {
5824 player->SetRuneCooldown(i, 0);
5825 player->SetGracePeriod(i, player->IsInCombat()); // xinef: reset grace period
5826 }
5827 }
5828 }
5829
5830 // is needed to push through to the client that the rune is active
5831 //player->ResyncRunes(MAX_RUNES);
5832 m_caster->CastSpell(m_caster, 47804, true);
5833}
@ RUNE_FROST
Definition Player.h:406
void SetRuneCooldown(uint8 index, uint32 cooldown)
Definition Player.h:2526
uint8 GetRunesState() const
Definition Player.h:2515
void SetGracePeriod(uint8 index, uint32 period)
Definition Player.h:2527
RuneType GetBaseRune(uint8 index) const
Definition Player.h:2516

References Unit::CastSpell(), CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, damage, effectHandleMode, SpellInfo::Effects, Player::GetBaseRune(), Player::GetCurrentRune(), Player::GetRuneCooldown(), Player::GetRunesState(), SpellInfo::Id, Player::IsClass(), Unit::IsInCombat(), Object::IsPlayer(), m_caster, m_runesState, m_spellInfo, MAX_RUNES, RUNE_DEATH, RUNE_FROST, Player::SetGracePeriod(), Player::SetRuneCooldown(), SPELL_EFFECT_HANDLE_LAUNCH, and Object::ToPlayer().

◆ EffectActivateSpec()

void Spell::EffectActivateSpec ( SpellEffIndex  effIndex)
6138{
6140 return;
6141
6142 if (!unitTarget)
6143 return;
6144
6145 if (Player* player = unitTarget->ToPlayer())
6146 {
6147 player->ActivateSpec(damage - 1); // damage is 1 or 2, spec is 0 or 1
6148 }
6149}

References damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectAddComboPoints()

void Spell::EffectAddComboPoints ( SpellEffIndex  effIndex)
4082{
4084 {
4085 return;
4086 }
4087
4088 if (!unitTarget || damage <= 0)
4089 {
4090 return;
4091 }
4092
4094}
void AddComboPointGain(Unit *target, int8 amount)
Definition Spell.h:553

References AddComboPointGain(), damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectAddExtraAttacks()

void Spell::EffectAddExtraAttacks ( SpellEffIndex  effIndex)
4664{
4666 {
4667 return;
4668 }
4669
4670 if (!unitTarget || !unitTarget->IsAlive())
4671 {
4672 return;
4673 }
4674
4676
4678}
void ExecuteLogEffectExtraAttacks(uint8 effIndex, Unit *victim, uint32 attCount)
Definition Spell.cpp:5145
void AddExtraAttacks(uint32 count)
Definition Unit.cpp:2801

References Unit::AddExtraAttacks(), damage, effectHandleMode, ExecuteLogEffectExtraAttacks(), Unit::IsAlive(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectAddFarsight()

void Spell::EffectAddFarsight ( SpellEffIndex  effIndex)
2718{
2720 return;
2721
2722 if (!m_caster->IsPlayer())
2723 return;
2724
2725 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2726 int32 duration = m_spellInfo->GetDuration();
2727 // Caster not in world, might be spell triggered from aura removal
2728 if (!m_caster->IsInWorld())
2729 return;
2730
2731 // Remove old farsight if exist
2732 bool updateViewerVisibility = m_caster->RemoveDynObject(m_spellInfo->Id);
2733
2734 DynamicObject* dynObj = new DynamicObject();
2736 {
2737 delete dynObj;
2738 return;
2739 }
2740
2741 dynObj->SetDuration(duration);
2742 dynObj->SetCasterViewpoint(updateViewerVisibility);
2743}
@ DYNAMIC_OBJECT_FARSIGHT_FOCUS
Definition DynamicObject.h:31
void SetDuration(int32 newDuration)
Definition DynamicObject.cpp:198
void SetCasterViewpoint(bool updateViewerVisibility)
Definition DynamicObject.cpp:226
bool CreateDynamicObject(ObjectGuid::LowType guidlow, Unit *caster, uint32 spellId, Position const &pos, float radius, DynamicObjectType type)
Definition DynamicObject.cpp:97
ObjectGuid::LowType GenerateLowGuid()
Definition Map.h:470
int32 GetDuration() const
Definition SpellInfo.cpp:2345

References DynamicObject::CreateDynamicObject(), destTarget, DYNAMIC_OBJECT_FARSIGHT_FOCUS, DynamicObject, effectHandleMode, SpellInfo::Effects, Map::GenerateLowGuid(), SpellInfo::GetDuration(), WorldObject::GetMap(), SpellInfo::Id, Object::IsInWorld(), Object::IsPlayer(), m_caster, m_spellInfo, Unit::RemoveDynObject(), DynamicObject::SetCasterViewpoint(), DynamicObject::SetDuration(), and SPELL_EFFECT_HANDLE_HIT.

◆ EffectAddHonor()

void Spell::EffectAddHonor ( SpellEffIndex  effIndex)
2788{
2790 return;
2791
2792 if (!unitTarget->IsPlayer())
2793 return;
2794
2795 // not scale value for item based reward (/10 value expected)
2796 if (m_CastItem)
2797 {
2798 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage / 10, false);
2799 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (item {}) for player: {}",
2801 return;
2802 }
2803
2804 // do not allow to add too many honor for player (50 * 21) = 1040 at level 70, or (50 * 31) = 1550 at level 80
2805 if (damage <= 50)
2806 {
2808 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, honor_reward, false);
2809 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (scale) to player: {}",
2810 m_spellInfo->Id, honor_reward, unitTarget->ToPlayer()->GetGUID().ToString());
2811 }
2812 else
2813 {
2814 //maybe we have correct honor_gain in damage already
2815 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage, false);
2816 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (non scale) for player: {}",
2818 }
2819}
std::string ToString() const
Definition ObjectGuid.cpp:47
bool RewardHonor(Unit *victim, uint32 groupsize, int32 honor=-1, bool awardXP=true)
Definition Player.cpp:6107
uint32 hk_honor_at_level(uint8 level, float multiplier=1.0f)
Definition Formulas.h:38

References damage, effectHandleMode, Object::GetEntry(), Object::GetGUID(), Unit::GetLevel(), Acore::Honor::hk_honor_at_level(), SpellInfo::Id, Object::IsPlayer(), LOG_DEBUG, m_CastItem, m_spellInfo, Player::RewardHonor(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectApplyAreaAura()

void Spell::EffectApplyAreaAura ( SpellEffIndex  effIndex)
1320{
1322 return;
1323
1324 if (!m_spellAura || !unitTarget)
1325 return;
1328}
WorldObject * GetOwner() const
Definition SpellAuras.h:107
void _ApplyEffectForTargets(uint8 effIndex)
Definition SpellAuras.cpp:735

References Aura::_ApplyEffectForTargets(), ASSERT, effectHandleMode, Aura::GetOwner(), m_spellAura, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectApplyAura()

void Spell::EffectApplyAura ( SpellEffIndex  effIndex)

◆ EffectApplyGlyph()

void Spell::EffectApplyGlyph ( SpellEffIndex  effIndex)
4323{
4325 return;
4326
4328 return;
4329
4330 Player* player = m_caster->ToPlayer();
4331
4332 // glyph sockets level requirement
4333 uint8 minLevel = 0;
4334 switch (m_glyphIndex)
4335 {
4336 case 0:
4337 case 1:
4338 minLevel = 15;
4339 break;
4340 case 2:
4341 minLevel = 50;
4342 break;
4343 case 3:
4344 minLevel = 30;
4345 break;
4346 case 4:
4347 minLevel = 70;
4348 break;
4349 case 5:
4350 minLevel = 80;
4351 break;
4352 }
4353 if (minLevel && m_caster->GetLevel() < minLevel)
4354 {
4356 return;
4357 }
4358
4359 // apply new one
4360 if (uint32 glyph = m_spellInfo->Effects[effIndex].MiscValue)
4361 {
4362 if (GlyphPropertiesEntry const* glyphEntry = sGlyphPropertiesStore.LookupEntry(glyph))
4363 {
4364 if (GlyphSlotEntry const* glyphSlotEntry = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex)))
4365 {
4366 if (glyphEntry->TypeFlags != glyphSlotEntry->TypeFlags)
4367 {
4369 return; // glyph slot mismatch
4370 }
4371 }
4372
4373 // remove old glyph aura
4374 if (uint32 oldGlyph = player->GetGlyph(m_glyphIndex))
4375 if (GlyphPropertiesEntry const* oldGlyphEntry = sGlyphPropertiesStore.LookupEntry(oldGlyph))
4376 {
4377 player->RemoveAurasDueToSpell(oldGlyphEntry->SpellId);
4378
4379 // Removed any triggered auras
4380 Unit::AuraMap& ownedAuras = player->GetOwnedAuras();
4381 for (Unit::AuraMap::iterator iter = ownedAuras.begin(); iter != ownedAuras.end();)
4382 {
4383 Aura* aura = iter->second;
4384 if (SpellInfo const* triggeredByAuraSpellInfo = aura->GetTriggeredByAuraSpellInfo())
4385 {
4386 if (triggeredByAuraSpellInfo->Id == oldGlyphEntry->SpellId)
4387 {
4388 player->RemoveOwnedAura(iter);
4389 continue;
4390 }
4391 }
4392 ++iter;
4393 }
4394
4395 player->SendLearnPacket(oldGlyphEntry->SpellId, false); // Send packet to properly handle client-side spell tooltips
4396 }
4397
4398 player->SendLearnPacket(glyphEntry->SpellId, true); // Send packet to properly handle client-side spell tooltips
4400 player->SetGlyph(m_glyphIndex, glyph, !player->GetSession()->PlayerLoading());
4401 player->SendTalentsInfoData(false);
4402 }
4403 }
4404}
DBCStorage< GlyphSlotEntry > sGlyphSlotStore(GlyphSlotfmt)
#define MAX_GLYPH_SLOT_INDEX
Definition SharedDefines.h:687
@ SPELL_FAILED_GLYPH_SOCKET_LOCKED
Definition SharedDefines.h:1137
@ SPELL_FAILED_INVALID_GLYPH
Definition SharedDefines.h:1135
@ TRIGGERED_FULL_MASK
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
Definition SpellDefines.h:150
SpellInfo const * GetTriggeredByAuraSpellInfo() const
Definition SpellAuras.cpp:2761
void SendTalentsInfoData(bool pet)
Definition Player.cpp:14448
void SendLearnPacket(uint32 spellId, bool learn)
Definition Player.cpp:3045
uint32 GetGlyph(uint8 slot) const
Definition Player.h:1769
uint32 GetGlyphSlot(uint8 slot) const
Definition Player.h:1760
void SetGlyph(uint8 slot, uint32 glyph, bool save)
Definition Player.h:1761
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:4770
std::multimap< uint32, Aura * > AuraMap
Definition Unit.h:625
AuraMap & GetOwnedAuras()
Definition Unit.h:1298
bool PlayerLoading() const
Definition WorldSession.h:372
Definition DBCStructure.h:1030

References Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, Player::GetGlyph(), Player::GetGlyphSlot(), Unit::GetLevel(), Unit::GetOwnedAuras(), Player::GetSession(), Aura::GetTriggeredByAuraSpellInfo(), Object::IsPlayer(), m_caster, m_glyphIndex, m_spellInfo, MAX_GLYPH_SLOT_INDEX, WorldSession::PlayerLoading(), Unit::RemoveAurasDueToSpell(), Unit::RemoveOwnedAura(), SendCastResult(), Player::SendLearnPacket(), Player::SendTalentsInfoData(), Player::SetGlyph(), sGlyphPropertiesStore, sGlyphSlotStore, SPELL_EFFECT_HANDLE_HIT, SPELL_FAILED_GLYPH_SOCKET_LOCKED, SPELL_FAILED_INVALID_GLYPH, Object::ToPlayer(), TRIGGERED_FULL_MASK, TRIGGERED_IGNORE_CASTER_AURASTATE, and TRIGGERED_IGNORE_SHAPESHIFT.

◆ EffectBind()

void Spell::EffectBind ( SpellEffIndex  effIndex)
6271{
6273 return;
6274
6275 if (!unitTarget)
6276 return;
6277
6278 Player* player = unitTarget->ToPlayer();
6279 if (!player)
6280 {
6281 return;
6282 }
6283
6284 WorldLocation homeLoc;
6285 uint32 areaId = player->GetAreaId();
6286
6287 if (m_spellInfo->Effects[effIndex].MiscValue)
6288 areaId = m_spellInfo->Effects[effIndex].MiscValue;
6289
6290 if (m_targets.HasDst())
6291 homeLoc.WorldRelocate(*destTarget);
6292 else
6293 {
6294 homeLoc = player->GetWorldLocation();
6295 }
6296
6297 player->SetHomebind(homeLoc, areaId);
6298
6299 // binding
6300 WorldPacket data(SMSG_BINDPOINTUPDATE, 4 + 4 + 4 + 4 + 4);
6301 data << float(homeLoc.GetPositionX());
6302 data << float(homeLoc.GetPositionY());
6303 data << float(homeLoc.GetPositionZ());
6304 data << uint32(homeLoc.GetMapId());
6305 data << uint32(areaId);
6306 player->SendDirectMessage(&data);
6307
6308 LOG_DEBUG("spells.aura", "EffectBind: New homebind X: {}, Y: {}, Z: {}, MapId: {}, AreaId: {}",
6309 homeLoc.GetPositionX(), homeLoc.GetPositionY(), homeLoc.GetPositionZ(), homeLoc.GetMapId(), areaId);
6310 // zone update
6311 data.Initialize(SMSG_PLAYERBOUND, 8 + 4);
6312 data << m_caster->GetGUID();
6313 data << uint32(areaId);
6314 player->SendDirectMessage(&data);
6315}
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:5728
void SetHomebind(WorldLocation const &loc, uint32 areaId)
Definition PlayerStorage.cpp:4896
Definition Position.h:255
void WorldRelocate(const WorldLocation &loc)
Definition Position.h:263
void GetWorldLocation(uint32 &mapId, float &x, float &y) const
Definition Position.h:285
@ SMSG_BINDPOINTUPDATE
Definition Opcodes.h:371
@ SMSG_PLAYERBOUND
Definition Opcodes.h:374

References destTarget, effectHandleMode, SpellInfo::Effects, WorldObject::GetAreaId(), Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), WorldLocation::GetWorldLocation(), SpellCastTargets::HasDst(), WorldPacket::Initialize(), LOG_DEBUG, m_caster, m_spellInfo, m_targets, Player::SendDirectMessage(), Player::SetHomebind(), SMSG_BINDPOINTUPDATE, SMSG_PLAYERBOUND, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), unitTarget, and WorldLocation::WorldRelocate().

◆ EffectBlock()

void Spell::EffectBlock ( SpellEffIndex  effIndex)
4690{
4692 return;
4693
4694 if (m_caster->IsPlayer())
4695 m_caster->ToPlayer()->SetCanBlock(true);
4696}
void SetCanBlock(bool value)
Definition Player.cpp:13158

References effectHandleMode, Object::IsPlayer(), m_caster, Player::SetCanBlock(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectCastButtons()

void Spell::EffectCastButtons ( SpellEffIndex  effIndex)

Action button data is unverified when it's set so it can be "hacked" to contain invalid spells, so filter here.

6198{
6200 return;
6201
6202 if (!m_caster->IsPlayer())
6203 return;
6204
6205 Player* p_caster = m_caster->ToPlayer();
6206 uint32 button_id = m_spellInfo->Effects[effIndex].MiscValue + 132;
6207 uint32 n_buttons = m_spellInfo->Effects[effIndex].MiscValueB;
6208
6209 for (; n_buttons; --n_buttons, ++button_id)
6210 {
6211 ActionButton const* ab = p_caster->GetActionButton(button_id);
6212 if (!ab || ab->GetType() != ACTION_BUTTON_SPELL)
6213 continue;
6214
6217 uint32 spell_id = ab->GetAction();
6218 if (!spell_id)
6219 continue;
6220
6221 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
6222 if (!spellInfo)
6223 continue;
6224
6225 if (!p_caster->HasSpell(spell_id) || p_caster->HasSpellCooldown(spell_id))
6226 continue;
6227
6229 continue;
6230
6231 uint32 cost = spellInfo->CalcPowerCost(m_caster, spellInfo->GetSchoolMask(), this);
6232 if (m_caster->GetPower(POWER_MANA) < cost)
6233 continue;
6234
6236 m_caster->CastSpell(m_caster, spell_id, triggerFlags);
6237 }
6238}
@ ACTION_BUTTON_SPELL
Definition Player.h:230
@ SPELL_ATTR7_CAN_BE_MULTI_CAST
Definition SharedDefines.h:657
ActionButton const * GetActionButton(uint8 button)
Definition Player.cpp:5687
bool HasSpell(uint32 spell) const override
Definition Player.cpp:3904
Definition Player.h:248
uint32 GetAction() const
Definition Player.h:256
ActionButtonType GetType() const
Definition Player.h:255

References ACTION_BUTTON_SPELL, SpellInfo::CalcPowerCost(), Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, ActionButton::GetAction(), Player::GetActionButton(), Unit::GetPower(), SpellInfo::GetSchoolMask(), ActionButton::GetType(), SpellInfo::HasAttribute(), Player::HasSpell(), Player::HasSpellCooldown(), Object::IsPlayer(), m_caster, m_spellInfo, POWER_MANA, SPELL_ATTR7_CAN_BE_MULTI_CAST, SPELL_EFFECT_HANDLE_HIT, sSpellMgr, Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_CAST_IN_PROGRESS, and TRIGGERED_IGNORE_GCD.

◆ EffectCharge()

void Spell::EffectCharge ( SpellEffIndex  effIndex)
4909{
4911 {
4912 if (!unitTarget)
4913 return;
4914
4915 ObjectGuid targetGUID = ObjectGuid::Empty;
4916 Player* player = m_caster->ToPlayer();
4917 if (player)
4918 {
4919 // charge changes fall time
4921
4923 {
4924 targetGUID = unitTarget->GetGUID();
4925 }
4926 }
4927
4928 float speed = G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) ? m_spellInfo->Speed : SPEED_CHARGE;
4929 // Spell is not using explicit target - no generated path
4930 if (!m_preGeneratedPath)
4931 {
4933 m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speed, EVENT_CHARGE, nullptr, false, 0.0f, targetGUID);
4934 }
4935 else
4936 {
4937 m_caster->GetMotionMaster()->MoveCharge(*m_preGeneratedPath, speed, targetGUID);
4938 }
4939
4940 if (player)
4941 {
4942 sScriptMgr->AnticheatSetUnderACKmount(player);
4943 }
4944 }
4945}
#define SPEED_CHARGE
Definition MotionMaster.h:109
@ EVENT_CHARGE
Definition SharedDefines.h:3577
void MoveCharge(float x, float y, float z, float speed=SPEED_CHARGE, uint32 id=EVENT_CHARGE, const Movement::PointsArray *path=nullptr, bool generatePath=false, float orientation=0.0f, ObjectGuid targetGUID=ObjectGuid::Empty)
The unit will charge the target. Doesn't work with UNIT_FLAG_DISABLE_MOVE.
Definition MotionMaster.cpp:705
static ObjectGuid const Empty
Definition ObjectGuid.h:120
void SetFallInformation(uint32 time, float z)
Definition Player.h:2347
MotionMaster * GetMotionMaster()
Definition Unit.h:1676
Position GetFirstCollisionPosition(float startX, float startY, float startZ, float destX, float destY)
Definition Object.cpp:2814
Definition Position.h:27
float m_positionZ
Definition Position.h:57
float GetRelativeAngle(const Position *pos) const
Definition Position.h:201
float m_positionX
Definition Position.h:55
float m_positionY
Definition Position.h:56

References effectHandleMode, ObjectGuid::Empty, EVENT_CHARGE, Unit::GetCombatReach(), WorldObject::GetFirstCollisionPosition(), GameTime::GetGameTime(), Object::GetGUID(), Unit::GetMotionMaster(), Position::GetPositionZ(), Position::GetRelativeAngle(), Unit::GetTarget(), SpellInfo::HasAttribute(), SpellInfo::IsPositive(), m_caster, Position::m_positionX, Position::m_positionY, Position::m_positionZ, m_preGeneratedPath, m_spellInfo, MotionMaster::MoveCharge(), Player::SetFallInformation(), SpellInfo::Speed, SPEED_CHARGE, SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectChargeDest()

◆ EffectCreateItem()

void Spell::EffectCreateItem ( SpellEffIndex  effIndex)
1777{
1779 return;
1780
1781 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1782 ExecuteLogEffectCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1783}
void ExecuteLogEffectCreateItem(uint8 effIndex, uint32 entry)
Definition Spell.cpp:5173
void DoCreateItem(uint8 effIndex, uint32 itemId)
Definition SpellEffects.cpp:1647

References DoCreateItem(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectCreateItem(), m_spellInfo, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectCreateItem2()

void Spell::EffectCreateItem2 ( SpellEffIndex  effIndex)
Todo:
: ExecuteLogEffectCreateItem(i, m_spellInfo->Effects[i].ItemType);
1786{
1788 return;
1789
1790 if (!unitTarget)
1791 return;
1792
1793 Player* player = unitTarget->ToPlayer();
1794 if (!player)
1795 {
1796 return;
1797 }
1798
1799 uint32 itemId = m_spellInfo->Effects[effIndex].ItemType;
1800
1801 if (itemId)
1802 DoCreateItem(effIndex, itemId);
1803
1804 // special case: fake item replaced by generate using spell_loot_template
1806 {
1807 if (itemId)
1808 {
1809 if (!player->HasItemCount(itemId))
1810 return;
1811
1812 // remove reagent
1813 uint32 count = 1;
1814 player->DestroyItemCount(itemId, count, true);
1815
1816 // create some random items
1818 }
1819 else
1820 player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell); // create some random items
1821 }
1823}
LootStore LootTemplates_Spell("spell_loot_template", "spell id (random item creating)", false)
void AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore const &store, bool broadcast=false)
Definition Player.cpp:13513
void DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check=false)
Definition PlayerStorage.cpp:3114
bool IsLootCrafting() const
Definition SpellInfo.cpp:920

References Player::AutoStoreLoot(), Player::DestroyItemCount(), DoCreateItem(), effectHandleMode, SpellInfo::Effects, Player::HasItemCount(), SpellInfo::Id, SpellInfo::IsLootCrafting(), LootTemplates_Spell, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectCreateRandomItem()

void Spell::EffectCreateRandomItem ( SpellEffIndex  effIndex)
Todo:
: ExecuteLogEffectCreateItem(i, m_spellInfo->Effects[i].ItemType);
1826{
1828 return;
1829
1830 if (!unitTarget)
1831 return;
1832
1833 Player* player = unitTarget->ToPlayer();
1834 if (!player)
1835 {
1836 return;
1837 }
1838
1839 // create some random items
1842}

References Player::AutoStoreLoot(), effectHandleMode, SpellInfo::Id, LootTemplates_Spell, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectCreateTamedPet()

void Spell::EffectCreateTamedPet ( SpellEffIndex  effIndex)
5836{
5838 return;
5839
5841 return;
5842
5843 uint32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5844 Pet* pet = unitTarget->CreateTamedPetFrom(creatureEntry, m_spellInfo->Id);
5845 if (!pet)
5846 return;
5847
5848 // add to world
5849 pet->GetMap()->AddToMap(pet->ToCreature(), true);
5850
5851 // unitTarget has pet now
5852 unitTarget->SetMinion(pet, true);
5853
5854 pet->InitTalentForLevel();
5855
5856 if (unitTarget->IsPlayer())
5857 {
5860 }
5861}
@ CLASS_HUNTER
Definition SharedDefines.h:143
bool AddToMap(T *, bool checkTransport=false)
Definition Map.cpp:300
void InitTalentForLevel()
Definition Pet.cpp:2228
void SavePetToDB(PetSaveMode mode)
Definition Pet.cpp:502
void PetSpellInitialize()
Definition Player.cpp:9569
void SetMinion(Minion *minion, bool apply)
Definition Unit.cpp:10780
Pet * CreateTamedPetFrom(Creature *creatureTarget, uint32 spell_id=0)
Definition Unit.cpp:17434

References Map::AddToMap(), CLASS_CONTEXT_PET, CLASS_HUNTER, Unit::CreateTamedPetFrom(), effectHandleMode, SpellInfo::Effects, WorldObject::GetMap(), Unit::GetPetGUID(), SpellInfo::Id, Pet::InitTalentForLevel(), Unit::IsClass(), Object::IsPlayer(), m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), Unit::SetMinion(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), and unitTarget.

◆ EffectDestroyAllTotems()

void Spell::EffectDestroyAllTotems ( SpellEffIndex  effIndex)
5243{
5245 return;
5246
5247 int32 mana = 0;
5248 for (uint8 slot = SUMMON_SLOT_TOTEM_FIRE; slot < MAX_TOTEM_SLOT; ++slot)
5249 {
5250 if (!m_caster->m_SummonSlot[slot])
5251 continue;
5252
5254 if (totem && totem->IsTotem())
5255 {
5256 uint32 spell_id = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
5257 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
5258 if (spellInfo)
5259 {
5260 mana += spellInfo->ManaCost;
5262 }
5263 totem->ToTotem()->UnSummon();
5264 }
5265 }
5266 ApplyPct(mana, damage);
5267 if (mana)
5268 m_caster->CastCustomSpell(m_caster, 39104, &mana, nullptr, nullptr, true);
5269}
#define MAX_TOTEM_SLOT
Definition SharedDefines.h:3572
@ SUMMON_SLOT_TOTEM_FIRE
Definition SharedDefines.h:3562
@ UNIT_CREATED_BY_SPELL
Definition UpdateFields.h:138
T ApplyPct(T &base, U pct)
Definition Util.h:73
Creature * GetCreature(ObjectGuid const guid)
Definition Map.cpp:2364
uint32 ManaCostPercentage
Definition SpellInfo.h:368
uint32 ManaCost
Definition SpellInfo.h:364
void UnSummon(uint32 msTime=0) override
Definition Totem.cpp:122
Totem * ToTotem()
Definition Unit.h:685
SpellCastResult CastCustomSpell(Unit *victim, uint32 spellId, int32 const *bp0, int32 const *bp1, int32 const *bp2, bool triggered, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition Unit.cpp:1251
uint32 GetCreateMana() const
Definition Unit.h:1074
ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT]
Definition Unit.h:1997

References ApplyPct(), CalculatePct(), Unit::CastCustomSpell(), damage, effectHandleMode, Unit::GetCreateMana(), Map::GetCreature(), WorldObject::GetMap(), Object::GetUInt32Value(), Unit::IsTotem(), m_caster, Unit::m_SummonSlot, SpellInfo::ManaCost, SpellInfo::ManaCostPercentage, MAX_TOTEM_SLOT, SPELL_EFFECT_HANDLE_HIT, sSpellMgr, SUMMON_SLOT_TOTEM_FIRE, Unit::ToTotem(), UNIT_CREATED_BY_SPELL, and Totem::UnSummon().

◆ EffectDiscoverTaxi()

void Spell::EffectDiscoverTaxi ( SpellEffIndex  effIndex)
5864{
5866 return;
5867
5868 if (!unitTarget)
5869 return;
5870
5871 Player* player = unitTarget->ToPlayer();
5872 if (!player)
5873 {
5874 return;
5875 }
5876
5877 uint32 nodeid = m_spellInfo->Effects[effIndex].MiscValue;
5878 if (sTaxiNodesStore.LookupEntry(nodeid))
5879 player->GetSession()->SendDiscoverNewTaxiNode(nodeid);
5880}
DBCStorage< TaxiNodesEntry > sTaxiNodesStore(TaxiNodesEntryfmt)
void SendDiscoverNewTaxiNode(uint32 nodeid)
Definition TaxiHandler.cpp:151

References effectHandleMode, SpellInfo::Effects, Player::GetSession(), m_spellInfo, WorldSession::SendDiscoverNewTaxiNode(), SPELL_EFFECT_HANDLE_HIT_TARGET, sTaxiNodesStore, Object::ToPlayer(), and unitTarget.

◆ EffectDisEnchant()

void Spell::EffectDisEnchant ( SpellEffIndex  effIndex)
4460{
4462 return;
4463
4465 return;
4466
4467 if (Player* caster = m_caster->ToPlayer())
4468 {
4469 caster->UpdateCraftSkill(m_spellInfo->Id);
4470 caster->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING);
4471 }
4472
4473 // item will be removed at disenchanting end
4474}
@ LOOT_DISENCHANTING
Definition LootMgr.h:83

References ItemTemplate::DisenchantID, effectHandleMode, Object::GetGUID(), Item::GetTemplate(), SpellInfo::Id, itemTarget, LOOT_DISENCHANTING, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and Object::ToPlayer().

◆ EffectDismissPet()

void Spell::EffectDismissPet ( SpellEffIndex  effIndex)
4546{
4548 return;
4549
4550 if (!unitTarget || !unitTarget->IsPet())
4551 return;
4552
4553 Pet* pet = unitTarget->ToPet();
4554
4555 ExecuteLogEffectUnsummonObject(effIndex, pet);
4557}
@ PET_SAVE_NOT_IN_SLOT
Definition PetDefines.h:45
void Remove(PetSaveMode mode, bool returnreagent=false)
Definition Pet.cpp:881
void ExecuteLogEffectUnsummonObject(uint8 effIndex, WorldObject *obj)
Definition Spell.cpp:5191

References effectHandleMode, ExecuteLogEffectUnsummonObject(), Unit::IsPet(), PET_SAVE_NOT_IN_SLOT, Pet::Remove(), SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), and unitTarget.

◆ EffectDispel()

void Spell::EffectDispel ( SpellEffIndex  effIndex)
2567{
2569 return;
2570
2571 if (!unitTarget)
2572 return;
2573
2574 // Create dispel mask by dispel type
2575 uint32 dispel_type = m_spellInfo->Effects[effIndex].MiscValue;
2576 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(dispel_type));
2577
2578 DispelChargesList dispel_list;
2579 unitTarget->GetDispellableAuraList(m_caster, dispelMask, dispel_list, m_spellInfo);
2580 if (dispel_list.empty())
2581 return;
2582
2583 // Ok if exist some buffs for dispel try dispel it
2584 uint32 failCount = 0;
2585 DispelChargesList success_list;
2586 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
2587 // dispel N = damage buffs (or while exist buffs for dispel)
2588 for (int32 count = 0; count < damage && !dispel_list.empty();)
2589 {
2590 // Random select buff for dispel
2591 DispelChargesList::iterator itr = dispel_list.begin();
2592 std::advance(itr, urand(0, dispel_list.size() - 1));
2593
2594 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(m_caster));
2595 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
2596 if (!chance)
2597 {
2598 dispel_list.erase(itr);
2599 continue;
2600 }
2601 else
2602 {
2603 if (roll_chance_i(chance))
2604 {
2605 bool alreadyListed = false;
2606 for (DispelChargesList::iterator successItr = success_list.begin(); successItr != success_list.end(); ++successItr)
2607 {
2608 if (successItr->first->GetId() == itr->first->GetId())
2609 {
2610 ++successItr->second;
2611 alreadyListed = true;
2612 }
2613 }
2614 if (!alreadyListed)
2615 success_list.push_back(std::make_pair(itr->first, 1));
2616 --itr->second;
2617 if (itr->second <= 0)
2618 dispel_list.erase(itr);
2619 }
2620 else
2621 {
2622 if (!failCount)
2623 {
2624 // Failed to dispell
2625 dataFail << m_caster->GetGUID(); // Caster GUID
2626 dataFail << unitTarget->GetGUID(); // Victim GUID
2627 dataFail << uint32(m_spellInfo->Id); // dispel spell id
2628 }
2629 ++failCount;
2630 dataFail << uint32(itr->first->GetId()); // Spell Id
2631 }
2632 ++count;
2633 }
2634 }
2635
2636 if (failCount)
2637 m_caster->SendMessageToSet(&dataFail, true);
2638
2639 // put in combat
2642
2643 if (success_list.empty())
2644 return;
2645
2646 WorldPacket dataSuccess(SMSG_SPELLDISPELLOG, 8 + 8 + 4 + 1 + 4 + success_list.size() * 5);
2647 // Send packet header
2648 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
2649 dataSuccess << m_caster->GetPackGUID(); // Caster GUID
2650 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
2651 dataSuccess << uint8(0); // not used
2652 dataSuccess << uint32(success_list.size()); // count
2653 for (DispelChargesList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
2654 {
2655 // Send dispelled spell info
2656 dataSuccess << uint32(itr->first->GetId()); // Spell Id
2657 dataSuccess << uint8(0); // 0 - dispelled !=0 cleansed
2658 unitTarget->RemoveAurasDueToSpellByDispel(itr->first->GetId(), m_spellInfo->Id, itr->first->GetCasterGUID(), m_caster, itr->second);
2659 }
2660 m_caster->SendMessageToSet(&dataSuccess, true);
2661
2662 // On success dispel
2663 // Devour Magic
2665 {
2666 int32 heal_amount = m_spellInfo->Effects[EFFECT_1].CalcValue();
2667 m_caster->CastCustomSpell(m_caster, 19658, &heal_amount, nullptr, nullptr, true);
2668 // Glyph of Felhunter
2669 if (Unit* owner = m_caster->GetOwner())
2670 if (owner->GetAura(56249))
2671 owner->CastCustomSpell(owner, 19658, &heal_amount, nullptr, nullptr, true);
2672 }
2673}
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:44
@ SPELLFAMILY_WARLOCK
Definition SharedDefines.h:3799
@ SPELLCATEGORY_DEVOUR_MAGIC
Definition SpellMgr.h:40
uint32 GetCategory() const
Definition SpellInfo.cpp:866
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId, ObjectGuid casterGUID, Unit *dispeller, uint8 chargesRemoved=1)
Definition Unit.cpp:5007
@ SMSG_DISPEL_FAILED
Definition Opcodes.h:640
@ SMSG_SPELLDISPELLOG
Definition Opcodes.h:665

References Unit::CastCustomSpell(), damage, EFFECT_1, effectHandleMode, SpellInfo::Effects, SpellInfo::GetCategory(), Unit::GetDispellableAuraList(), SpellInfo::GetDispelMask(), Object::GetGUID(), Unit::getHostileRefMgr(), Unit::GetOwner(), Object::GetPackGUID(), SpellInfo::Id, Unit::IsFriendlyTo(), m_caster, m_spellInfo, Unit::RemoveAurasDueToSpellByDispel(), roll_chance_i(), WorldObject::SendMessageToSet(), SMSG_DISPEL_FAILED, SMSG_SPELLDISPELLOG, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLCATEGORY_DEVOUR_MAGIC, SPELLFAMILY_WARLOCK, SpellInfo::SpellFamilyName, HostileRefMgr::threatAssist(), unitTarget, and urand().

◆ EffectDispelMechanic()

void Spell::EffectDispelMechanic ( SpellEffIndex  effIndex)
5148{
5150 return;
5151
5152 if (!unitTarget)
5153 return;
5154
5155 uint32 mechanic = m_spellInfo->Effects[effIndex].MiscValue;
5156
5157 std::queue<std::pair<uint32, ObjectGuid>> dispel_list;
5158
5159 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5160 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5161 {
5162 Aura* aura = itr->second;
5164 continue;
5166 {
5167 if ((aura->GetSpellInfo()->GetAllEffectsMechanicMask() & (1 << mechanic)))
5168 {
5169 dispel_list.push(std::make_pair(aura->GetId(), aura->GetCasterGUID()));
5170
5171 // spell only removes 1 bleed effect do not continue
5172 if (m_spellInfo->Effects[effIndex].BasePoints == 1)
5173 {
5174 break;
5175 }
5176 }
5177 }
5178 }
5179
5180 for (; dispel_list.size(); dispel_list.pop())
5181 {
5182 unitTarget->RemoveAura(dispel_list.front().first, dispel_list.front().second, 0, AURA_REMOVE_BY_ENEMY_SPELL);
5183 }
5184
5185 // put in combat
5188}
@ AURA_REMOVE_BY_ENEMY_SPELL
Definition SpellAuraDefines.h:394
ObjectGuid GetCasterGUID() const
Definition SpellAuras.h:105
uint32 GetId() const
Definition SpellAuras.cpp:466
int32 CalcDispelChance(Unit *auraTarget, bool offensive) const
Definition SpellAuras.cpp:1182
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:4841

References AURA_REMOVE_BY_ENEMY_SPELL, Aura::CalcDispelChance(), effectHandleMode, SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Aura::GetApplicationOfTarget(), Aura::GetCasterGUID(), Object::GetGUID(), Unit::getHostileRefMgr(), Aura::GetId(), Unit::GetOwnedAuras(), Aura::GetSpellInfo(), Unit::IsFriendlyTo(), m_caster, m_spellInfo, Unit::RemoveAura(), roll_chance_i(), SPELL_EFFECT_HANDLE_HIT_TARGET, HostileRefMgr::threatAssist(), and unitTarget.

◆ EffectDistract()

void Spell::EffectDistract ( SpellEffIndex  effIndex)

@BUG Causes the player to stop moving.

2690{
2692 return;
2693
2694 // Check for possible target
2695 if (!unitTarget || unitTarget->IsEngaged())
2696 return;
2697
2698 // target must be OK to do this
2700 return;
2701
2704}
@ UNIT_STATE_CONFUSED
Definition UnitDefines.h:181
@ UNIT_STATE_FLEEING
Definition UnitDefines.h:177
@ UNIT_STATE_STUNNED
Definition UnitDefines.h:173
void MoveDistract(uint32 time)
Enable the target's distract movement. Doesn't work with UNIT_FLAG_DISABLE_MOVE and if the unit has M...
Definition MotionMaster.cpp:833
void SetFacingTo(float ori)
Definition Unit.cpp:20369
bool IsEngaged() const
Definition Unit.h:878
float GetAngle(const Position *pos) const
Definition Position.cpp:78

References damage, destTarget, effectHandleMode, Position::GetAngle(), Unit::GetMotionMaster(), Unit::HasUnitState(), IN_MILLISECONDS, Unit::IsEngaged(), MotionMaster::MoveDistract(), Unit::SetFacingTo(), SPELL_EFFECT_HANDLE_HIT_TARGET, UNIT_STATE_CONFUSED, UNIT_STATE_FLEEING, UNIT_STATE_STUNNED, and unitTarget.

◆ EffectDualWield()

void Spell::EffectDualWield ( SpellEffIndex  effIndex)
2676{
2678 return;
2679
2681}
virtual void SetCanDualWield(bool value)
Definition Unit.h:921

References effectHandleMode, Unit::SetCanDualWield(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectDuel()

void Spell::EffectDuel ( SpellEffIndex  effIndex)
4097{
4099 return;
4100
4101 if (!unitTarget || !m_caster->IsPlayer() || !unitTarget->IsPlayer())
4102 return;
4103
4104 Player* caster = m_caster->ToPlayer();
4105 Player* target = unitTarget->ToPlayer();
4106
4107 // caster or target already have requested duel
4108 if (caster->duel || target->duel || !target->GetSocial() || target->GetSocial()->HasIgnore(caster->GetGUID()))
4109 return;
4110
4111 // Players can only fight a duel in zones with this flag
4112 AreaTableEntry const* casterAreaEntry = sAreaTableStore.LookupEntry(caster->GetAreaId());
4113 if (casterAreaEntry && !(casterAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4114 {
4115 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4116 return;
4117 }
4118
4119 AreaTableEntry const* targetAreaEntry = sAreaTableStore.LookupEntry(target->GetAreaId());
4120 if (targetAreaEntry && !(targetAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4121 {
4122 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4123 return;
4124 }
4125
4126 //CREATE DUEL FLAG OBJECT
4127 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
4128 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
4129
4130 Map* map = m_caster->GetMap();
4131 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id,
4132 map, m_caster->GetPhaseMask(),
4136 m_caster->GetOrientation(), G3D::Quat(), 0, GO_STATE_READY))
4137 {
4138 delete pGameObj;
4139 return;
4140 }
4141
4144 int32 duration = m_spellInfo->GetDuration();
4145 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4146 pGameObj->SetSpellId(m_spellInfo->Id);
4147
4148 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4149
4150 m_caster->AddGameObject(pGameObj);
4151 map->AddToMap(pGameObj, true);
4152 //END
4153
4154 // Send request
4155 WorldPacket data(SMSG_DUEL_REQUESTED, 8 + 8);
4156 data << pGameObj->GetGUID();
4157 data << caster->GetGUID();
4158 caster->GetSession()->SendPacket(&data);
4159 target->GetSession()->SendPacket(&data);
4160
4161 // create duel-info
4162 bool isMounted = (GetSpellInfo()->Id == 62875);
4163 caster->duel = std::make_unique<DuelInfo>(target, caster, isMounted);
4164 target->duel = std::make_unique<DuelInfo>(caster, caster, isMounted);
4165
4166 caster->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4167 target->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4168
4169 sScriptMgr->OnPlayerDuelRequest(target, caster);
4170}
@ AREA_FLAG_ALLOW_DUELS
Definition DBCEnums.h:240
@ SPELL_FAILED_NO_DUELING
Definition SharedDefines.h:1039
@ PLAYER_DUEL_ARBITER
Definition UpdateFields.h:177
@ GAMEOBJECT_LEVEL
Definition UpdateFields.h:403
@ GAMEOBJECT_FACTION
Definition UpdateFields.h:402
virtual bool Create(ObjectGuid::LowType guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, G3D::Quat const &rotation, uint32 animprogress, GOState go_state, uint32 artKit=0)
Definition GameObject.cpp:254
void SetRespawnTime(int32 respawn)
Definition GameObject.cpp:1284
void SetSpellId(uint32 id)
Definition GameObject.h:176
void SetUInt32Value(uint16 index, uint32 value)
Definition Object.cpp:639
bool HasIgnore(ObjectGuid ignore_guid) const
Definition SocialMgr.cpp:193
PlayerSocial * GetSocial()
Definition Player.h:1149
void ExecuteLogEffectSummonObject(uint8 effIndex, WorldObject *obj)
Definition Spell.cpp:5185
Definition Transport.h:115
uint32 GetFaction() const
Definition Unit.h:803
void AddGameObject(GameObject *gameObj)
Definition Unit.cpp:6275
uint32 GetPhaseMask() const
Definition Object.h:513
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
Definition WorldSession.cpp:251
@ SMSG_DUEL_REQUESTED
Definition Opcodes.h:389
uint32 flags
Definition DBCStructure.h:524
float GetOrientation() const
Definition Position.h:124

References Unit::AddGameObject(), Map::AddToMap(), AREA_FLAG_ALLOW_DUELS, GameObject::Create(), Player::duel, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), AreaTableEntry::flags, GameObject, GAMEOBJECT_FACTION, GAMEOBJECT_LEVEL, Map::GenerateLowGuid(), WorldObject::GetAreaId(), SpellInfo::GetDuration(), Unit::GetFaction(), Object::GetGUID(), Unit::GetLevel(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Player::GetSession(), Player::GetSocial(), GetSpellInfo(), GO_STATE_READY, PlayerSocial::HasIgnore(), SpellInfo::Id, IN_MILLISECONDS, Object::IsPlayer(), m_caster, m_spellInfo, PLAYER_DUEL_ARBITER, sAreaTableStore, SendCastResult(), WorldSession::SendPacket(), Object::SetGuidValue(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), Object::SetUInt32Value(), SMSG_DUEL_REQUESTED, sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_FAILED_NO_DUELING, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectDummy()

void Spell::EffectDummy ( SpellEffIndex  effIndex)
663{
665 return;
666
668 return;
669
670 // selection by spell family
672 {
674 {
675 switch (m_spellInfo->Id)
676 {
677 // Trial of the Champion, Trample
678 case 67866:
679 {
681 unitTarget->CastSpell(unitTarget, 67867, false);
682 return;
683 }
684 // Trial of the Champion, Hammer of the Righteous
685 case 66867:
686 {
687 if (!unitTarget)
688 return;
689 if (unitTarget->HasAura(66940))
690 m_caster->CastSpell(unitTarget, 66903, true);
691 else
692 m_caster->CastSpell(unitTarget, 66904, true);
693 return;
694 }
695 case 17731:
696 case 69294:
697 {
699 return;
700
704 trigger->CastSpell(trigger, 17731, false);
705
706 return;
707 }
708 // HoL, Arc Weld
709 case 59086:
710 {
712 m_caster->CastSpell(m_caster, 59097, true);
713
714 return;
715 }
716 }
717 break;
718 }
720 switch (m_spellInfo->Id)
721 {
722 case 31789: // Righteous Defense (step 1)
723 {
724 if (!unitTarget)
725 return;
726 // not empty (checked), copy
728
729 // remove invalid attackers
730 for (Unit::AttackerSet::iterator aItr = attackers.begin(); aItr != attackers.end();)
731 if (!(*aItr)->IsValidAttackTarget(m_caster))
732 aItr = attackers.erase(aItr);
733 else
734 ++aItr;
735
736 // selected from list 3
737 uint32 maxTargets = std::min<uint32>(3, attackers.size());
738 for (uint32 i = 0; i < maxTargets; ++i)
739 {
740 Unit::AttackerSet::iterator aItr = attackers.begin();
741 std::advance(aItr, urand(0, attackers.size() - 1));
742 m_caster->CastSpell((*aItr), 31790, true);
743 attackers.erase(aItr);
744 }
745
746 return;
747 }
748 }
749 break;
751 // Hunger for Blood
752 if (m_spellInfo->Id == 51662)
753 {
754 m_caster->CastSpell(m_caster, 63848, true);
755 return;
756 }
757 break;
758 }
759
760 // pet auras
761 if (PetAura const* petSpell = sSpellMgr->GetPetAura(m_spellInfo->Id, effIndex))
762 {
763 m_caster->AddPetAura(petSpell);
764 return;
765 }
766
767 // normal DB scripted effect
768 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectDummy({})", m_spellInfo->Id, effIndex);
770
771 if (gameObjTarget)
772 {
773 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, gameObjTarget);
774 }
775 else if (unitTarget && unitTarget->IsCreature())
776 {
777 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, unitTarget->ToCreature());
778 }
779 else if (itemTarget)
780 {
781 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, itemTarget);
782 }
783}
ScriptMapMap sSpellScripts
Definition ObjectMgr.cpp:59
@ TEMPSUMMON_TIMED_DESPAWN
Definition Object.h:50
@ SPELLFAMILY_GENERIC
Definition SharedDefines.h:3794
@ SPELLFAMILY_PALADIN
Definition SharedDefines.h:3804
@ SPELLFAMILY_ROGUE
Definition SharedDefines.h:3802
@ UNIT_FIELD_MOUNTDISPLAYID
Definition UpdateFields.h:126
uint8 GetGoAnimProgress() const
Definition GameObject.h:208
time_t GetRespawnTime() const
Definition GameObject.h:183
void ScriptsStart(std::map< uint32, std::multimap< uint32, ScriptInfo > > const &scripts, uint32 id, Object *source, Object *target)
Put scripts in the execution queue.
Definition MapScripts.cpp:31
Definition SpellMgr.h:470
void AddPetAura(PetAura const *petSpell)
Definition Unit.cpp:17380
std::unordered_set< Unit * > AttackerSet
Definition Unit.h:622
AttackerSet const & getAttackers() const
Definition Unit.h:847
TempSummon * SummonCreature(uint32 id, const Position &pos, TempSummonType spwtype=TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime=0, uint32 vehId=0, SummonPropertiesEntry const *properties=nullptr, bool visibleBySummonerOnly=false) const
Definition Object.cpp:2334

References Unit::AddPetAura(), Unit::CastSpell(), effectHandleMode, gameObjTarget, Unit::getAttackers(), GameTime::GetGameTime(), GameObject::GetGoAnimProgress(), WorldObject::GetMap(), GameObject::GetRespawnTime(), Object::GetUInt32Value(), Unit::HasAura(), SpellInfo::Id, Object::IsCreature(), Unit::isMoving(), Object::IsPlayer(), Unit::IsVehicle(), itemTarget, LOG_DEBUG, m_caster, m_spellInfo, Map::ScriptsStart(), GameObject::SendCustomAnim(), GameObject::SetRespawnTime(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SPELLFAMILY_PALADIN, SPELLFAMILY_ROGUE, SpellInfo::SpellFamilyName, sScriptMgr, sSpellMgr, sSpellScripts, WorldObject::SummonCreature(), TEMPSUMMON_TIMED_DESPAWN, Object::ToCreature(), Object::ToPlayer(), UNIT_FIELD_MOUNTDISPLAYID, unitTarget, and urand().

◆ EffectDurabilityDamage()

void Spell::EffectDurabilityDamage ( SpellEffIndex  effIndex)
5272{
5274 return;
5275
5276 if (!unitTarget)
5277 return;
5278
5279 Player* player = unitTarget->ToPlayer();
5280 if (!player)
5281 {
5282 return;
5283 }
5284
5285 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5286
5287 // -1 means all player equipped items and -2 all items
5288 if (slot < 0)
5289 {
5290 player->DurabilityPointsLossAll(damage, (slot < -1));
5292 return;
5293 }
5294
5295 // invalid slot value
5296 if (slot >= INVENTORY_SLOT_BAG_END)
5297 return;
5298
5299 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5300 {
5301 player->DurabilityPointsLoss(item, damage);
5302 ExecuteLogEffectDurabilityDamage(effIndex, unitTarget, item->GetEntry(), slot);
5303 }
5304}
@ INVENTORY_SLOT_BAG_END
Definition Player.h:696
#define INVENTORY_SLOT_BAG_0
Definition Player.h:666
Item * GetItemByPos(uint16 pos) const
Definition PlayerStorage.cpp:441
void DurabilityPointsLossAll(int32 points, bool inventory)
Definition Player.cpp:4797
void DurabilityPointsLoss(Item *item, int32 points)
Definition Player.cpp:4823
void ExecuteLogEffectDurabilityDamage(uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
Definition Spell.cpp:5159

References damage, Player::DurabilityPointsLoss(), Player::DurabilityPointsLossAll(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectDurabilityDamage(), Object::GetEntry(), Player::GetItemByPos(), INVENTORY_SLOT_BAG_0, INVENTORY_SLOT_BAG_END, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectDurabilityDamagePCT()

void Spell::EffectDurabilityDamagePCT ( SpellEffIndex  effIndex)
5307{
5309 return;
5310
5311 if (!unitTarget)
5312 return;
5313
5314 Player* player = unitTarget->ToPlayer();
5315 if (!player)
5316 {
5317 return;
5318 }
5319
5320 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5321
5322 // FIXME: some spells effects have value -1/-2
5323 // Possibly its mean -1 all player equipped items and -2 all items
5324 if (slot < 0)
5325 {
5326 player->DurabilityLossAll(float(damage) / 100.0f, (slot < -1));
5327 return;
5328 }
5329
5330 // invalid slot value
5331 if (slot >= INVENTORY_SLOT_BAG_END)
5332 return;
5333
5334 if (damage <= 0)
5335 return;
5336
5337 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5338 player->DurabilityLoss(item, float(damage) / 100.0f);
5339}
void DurabilityLossAll(double percent, bool inventory)
Definition Player.cpp:4753
void DurabilityLoss(Item *item, double percent)
Definition Player.cpp:4779

References damage, Player::DurabilityLoss(), Player::DurabilityLossAll(), effectHandleMode, SpellInfo::Effects, Player::GetItemByPos(), INVENTORY_SLOT_BAG_0, INVENTORY_SLOT_BAG_END, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectEnchantHeldItem()

void Spell::EffectEnchantHeldItem ( SpellEffIndex  effIndex)
4407{
4409 return;
4410
4411 // this is only item spell effect applied to main-hand weapon of target player (players in area)
4412 if (!unitTarget)
4413 return;
4414
4415 Player* item_owner = unitTarget->ToPlayer();
4416 if (!item_owner)
4417 {
4418 return;
4419 }
4420
4422 if (!item)
4423 return;
4424
4425 // must be equipped
4426 if (!item->IsEquipped())
4427 return;
4428
4429 if (m_spellInfo->Effects[effIndex].MiscValue)
4430 {
4431 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
4432 int32 duration = m_spellInfo->GetDuration(); //Try duration index first ..
4433 if (!duration)
4434 duration = damage * IN_MILLISECONDS; //+1; //Base points after ..
4435 if (!duration)
4436 duration = 10 * IN_MILLISECONDS; //10 seconds for enchants which don't have listed duration
4437
4438 // Xinef: Venomhide poison, no other spell uses this effect...
4439 if (m_spellInfo->Id == 14792)
4440 duration = 5 * MINUTE * IN_MILLISECONDS;
4441
4442 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
4443 if (!pEnchant)
4444 return;
4445
4446 // Always go to temp enchantment slot
4448
4449 // Enchantment will not be applied if a different one already exists
4450 if (item->GetEnchantmentId(slot) && item->GetEnchantmentId(slot) != enchant_id)
4451 return;
4452
4453 // Apply the temporary enchantment
4454 item->SetEnchantment(slot, enchant_id, duration, pEnchant->charges, m_caster->GetGUID());
4455 item_owner->ApplyEnchantment(item, slot, true);
4456 }
4457}
EnchantmentSlot
Definition Item.h:168
@ TEMP_ENCHANTMENT_SLOT
Definition Item.h:170
@ EQUIPMENT_SLOT_MAINHAND
Definition Player.h:686
bool IsEquipped() const
Definition Item.cpp:789
void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges, ObjectGuid caster=ObjectGuid::Empty)
Definition Item.cpp:920
void ApplyEnchantment(Item *item, EnchantmentSlot slot, bool apply, bool apply_dur=true, bool ignore_condition=false)
Definition PlayerStorage.cpp:4297
uint32 charges
Definition DBCStructure.h:1844

References Player::ApplyEnchantment(), SpellItemEnchantmentEntry::charges, damage, effectHandleMode, SpellInfo::Effects, EQUIPMENT_SLOT_MAINHAND, SpellInfo::GetDuration(), Item::GetEnchantmentId(), Object::GetGUID(), Player::GetItemByPos(), SpellInfo::Id, IN_MILLISECONDS, INVENTORY_SLOT_BAG_0, Item::IsEquipped(), m_caster, m_spellInfo, MINUTE, Item::SetEnchantment(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), and unitTarget.

◆ EffectEnchantItemPerm()

void Spell::EffectEnchantItemPerm ( SpellEffIndex  effIndex)
2834{
2836 return;
2837
2838 if (!m_caster->IsPlayer())
2839 return;
2840 if (!itemTarget)
2841 return;
2842
2843 Player* p_caster = m_caster->ToPlayer();
2844
2845 // Handle vellums
2847 {
2848 // destroy one vellum from stack
2849 uint32 count = 1;
2850 p_caster->DestroyItemCount(itemTarget, count, true);
2851 unitTarget = p_caster;
2852 // and add a scroll
2853 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
2854 itemTarget = nullptr;
2855 m_targets.SetItemTarget(nullptr);
2856 }
2857 else
2858 {
2859 // do not increase skill if vellum used
2861 p_caster->UpdateCraftSkill(m_spellInfo->Id);
2862
2863 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2864 if (!enchant_id)
2865 return;
2866
2867 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2868 if (!pEnchant)
2869 return;
2870
2871 // item can be in trade slot and have owner diff. from caster
2872 Player* item_owner = itemTarget->GetOwner();
2873 if (!item_owner)
2874 return;
2875
2876 // remove old enchanting before applying new if equipped
2878
2880
2881 // add new enchanting if equipped
2883
2884 item_owner->RemoveTradeableItem(itemTarget);
2886 }
2887}
@ PERM_ENCHANTMENT_SLOT
Definition Item.h:169
void ClearSoulboundTradeable(Player *currentOwner)
Definition Item.cpp:1264
void RemoveTradeableItem(Item *item)
Definition PlayerStorage.cpp:4132
void SetItemTarget(Item *item)
Definition Spell.cpp:328

References Player::ApplyEnchantment(), Item::ClearSoulboundTradeable(), Player::DestroyItemCount(), DoCreateItem(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), Item::GetTemplate(), ItemTemplate::HasFlag(), SpellInfo::Id, Item::IsArmorVellum(), Object::IsPlayer(), Item::IsWeaponVellum(), ITEM_FLAG_NO_REAGENT_COST, itemTarget, m_caster, m_CastItem, m_spellInfo, m_targets, PERM_ENCHANTMENT_SLOT, Player::RemoveTradeableItem(), Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, Object::ToPlayer(), unitTarget, and Player::UpdateCraftSkill().

◆ EffectEnchantItemPrismatic()

void Spell::EffectEnchantItemPrismatic ( SpellEffIndex  effIndex)
2890{
2892 return;
2893
2894 if (!m_caster->IsPlayer())
2895 return;
2896 if (!itemTarget)
2897 return;
2898
2899 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2900 if (!enchant_id)
2901 return;
2902
2903 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2904 if (!pEnchant)
2905 return;
2906
2907 // support only enchantings with add socket in this slot
2908 {
2909 bool add_socket = false;
2910 for (uint8 i = 0; i < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++i)
2911 {
2912 if (pEnchant->type[i] == ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET)
2913 {
2914 add_socket = true;
2915 break;
2916 }
2917 }
2918 if (!add_socket)
2919 {
2920 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemPrismatic: attempt apply enchant spell {} with SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC ({}) but without ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET ({}), not suppoted yet.",
2922 return;
2923 }
2924 }
2925
2926 // item can be in trade slot and have owner diff. from caster
2927 Player* item_owner = itemTarget->GetOwner();
2928 if (!item_owner)
2929 return;
2930
2931 // remove old enchanting before applying new if equipped
2933
2935
2936 // add new enchanting if equipped
2938
2939 item_owner->RemoveTradeableItem(itemTarget);
2941}

References Player::ApplyEnchantment(), Item::ClearSoulboundTradeable(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), SpellInfo::Id, Object::IsPlayer(), ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET, itemTarget, LOG_ERROR, m_caster, m_spellInfo, MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS, PRISMATIC_ENCHANTMENT_SLOT, Player::RemoveTradeableItem(), Item::SetEnchantment(), SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC, SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, and SpellItemEnchantmentEntry::type.

◆ EffectEnchantItemTmp()

void Spell::EffectEnchantItemTmp ( SpellEffIndex  effIndex)
2944{
2946 return;
2947
2948 if (!m_caster->IsPlayer())
2949 return;
2950
2951 Player* p_caster = m_caster->ToPlayer();
2952
2953 // Rockbiter Weapon apply to both weapon
2954 if (!itemTarget)
2955 return;
2957 {
2958 uint32 spell_id = 0;
2959
2960 // enchanting spell selected by calculated damage-per-sec stored in Effect[1] base value
2961 // Note: damage calculated (correctly) with rounding int32(float(v)) but
2962 // RW enchantments applied damage int32(float(v)+0.5), this create 0..1 difference sometime
2963 switch (damage)
2964 {
2965 // Rank 1
2966 case 2:
2967 spell_id = 36744;
2968 break; // 0% [ 7% == 2, 14% == 2, 20% == 2]
2969 // Rank 2
2970 case 4:
2971 spell_id = 36753;
2972 break; // 0% [ 7% == 4, 14% == 4]
2973 case 5:
2974 spell_id = 36751;
2975 break; // 20%
2976 // Rank 3
2977 case 6:
2978 spell_id = 36754;
2979 break; // 0% [ 7% == 6, 14% == 6]
2980 case 7:
2981 spell_id = 36755;
2982 break; // 20%
2983 // Rank 4
2984 case 9:
2985 spell_id = 36761;
2986 break; // 0% [ 7% == 6]
2987 case 10:
2988 spell_id = 36758;
2989 break; // 14%
2990 case 11:
2991 spell_id = 36760;
2992 break; // 20%
2993 default:
2994 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemTmp: Damage {} not handled in S'RW", damage);
2995 return;
2996 }
2997
2998 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
2999 if (!spellInfo)
3000 {
3001 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemTmp: unknown spell id {}", spell_id);
3002 return;
3003 }
3004
3005 for (int j = BASE_ATTACK; j <= OFF_ATTACK; ++j)
3006 {
3007 if (Item* item = p_caster->GetWeaponForAttack(WeaponAttackType(j)))
3008 {
3009 if (item->IsFitToSpellRequirements(m_spellInfo))
3010 {
3011 Spell* spell = new Spell(m_caster, spellInfo, TRIGGERED_FULL_MASK);
3012 SpellCastTargets targets;
3013 targets.SetItemTarget(item);
3014 spell->prepare(&targets);
3015 }
3016 }
3017 }
3018 return;
3019 }
3020 if (!itemTarget)
3021 return;
3022
3023 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
3024
3025 if (!enchant_id)
3026 {
3027 LOG_ERROR("spells.effect", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have 0 as enchanting id", m_spellInfo->Id, effIndex);
3028 return;
3029 }
3030
3031 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
3032 if (!pEnchant)
3033 {
3034 LOG_ERROR("spells.effect", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have not existed enchanting id {} ", m_spellInfo->Id, effIndex, enchant_id);
3035 return;
3036 }
3037
3038 // select enchantment duration
3039 uint32 duration;
3040
3041 // rogue family enchantments exception by duration
3042 if (m_spellInfo->Id == 38615)
3043 duration = 1800; // 30 mins
3044 // other rogue family enchantments always 1 hour (some have spell damage=0, but some have wrong data in EffBasePoints)
3046 duration = 3600; // 1 hour
3047 // shaman family enchantments
3049 duration = 1800; // 30 mins
3050 // other cases with this SpellVisual already selected
3051 else if (m_spellInfo->SpellVisual[0] == 215)
3052 duration = 1800; // 30 mins
3053 // some fishing pole bonuses except Glow Worm which lasts full hour
3054 else if (m_spellInfo->SpellVisual[0] == 563 && m_spellInfo->Id != 64401)
3055 duration = 600; // 10 mins
3056 // shaman rockbiter enchantments
3057 else if (m_spellInfo->SpellVisual[0] == 0)
3058 duration = 1800; // 30 mins
3059 else if (m_spellInfo->Id == 29702)
3060 duration = 300; // 5 mins
3061 else if (m_spellInfo->Id == 37360)
3062 duration = 300; // 5 mins
3063 // default case
3064 else
3065 duration = 3600; // 1 hour
3066
3067 // item can be in trade slot and have owner diff. from caster
3068 Player* item_owner = itemTarget->GetOwner();
3069 if (!item_owner)
3070 return;
3071
3072 // remove old enchanting before applying new if equipped
3074
3075 itemTarget->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, duration * 1000, pEnchant->charges, m_caster->GetGUID());
3076
3077 // add new enchanting if equipped
3079
3080 item_owner->RemoveTradeableItem(itemTarget);
3082}
@ SPELLFAMILY_SHAMAN
Definition SharedDefines.h:3805
WeaponAttackType
Definition Unit.h:209
Definition Spell.h:118
std::array< uint32, 2 > SpellVisual
Definition SpellInfo.h:380
SpellCastResult prepare(SpellCastTargets const *targets, AuraEffect const *triggeredByAura=nullptr)
Definition Spell.cpp:3482

References Player::ApplyEnchantment(), BASE_ATTACK, SpellItemEnchantmentEntry::charges, Item::ClearSoulboundTradeable(), damage, effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), Player::GetWeaponForAttack(), SpellInfo::Id, Object::IsPlayer(), itemTarget, LOG_ERROR, m_caster, m_spellInfo, OFF_ATTACK, prepare(), Player::RemoveTradeableItem(), Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_ROGUE, SPELLFAMILY_SHAMAN, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellVisual, sSpellItemEnchantmentStore, sSpellMgr, TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), and TRIGGERED_FULL_MASK.

◆ EffectEnergize()

void Spell::EffectEnergize ( SpellEffIndex  effIndex)
1879{
1881 return;
1882
1883 if (!unitTarget)
1884 return;
1885 if (!unitTarget->IsAlive())
1886 return;
1887
1889 {
1891 return;
1892 }
1893
1894 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1895 return;
1896
1897 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1898
1901 return;
1902
1903 if (unitTarget->GetMaxPower(power) == 0)
1904 return;
1905
1906 // Some level depends spells
1907 int level_multiplier = 0;
1908 int level_diff = 0;
1909 switch (m_spellInfo->Id)
1910 {
1911 case 9512: // Restore Energy
1912 level_diff = m_caster->GetLevel() - 40;
1913 level_multiplier = 2;
1914 break;
1915 case 24571: // Blood Fury
1916 level_diff = m_caster->GetLevel() - 60;
1917 level_multiplier = 10;
1918 break;
1919 case 24532: // Burst of Energy
1920 level_diff = m_caster->GetLevel() - 60;
1921 level_multiplier = 4;
1922 break;
1923 case 31930: // Judgements of the Wise
1924 case 63375: // Improved Stormstrike
1925 case 68082: // Glyph of Seal of Command
1927 break;
1928 case 48542: // Revitalize
1930 break;
1931 case 71132: // Glyph of Shadow Word: Pain
1932 damage = int32(CalculatePct(unitTarget->GetCreateMana(), 1)); // set 1 as value, missing in dbc
1933 break;
1934 default:
1935 break;
1936 }
1937
1938 if (level_diff > 0)
1939 damage -= level_multiplier * level_diff;
1940
1941 if (damage < 0)
1942 return;
1943
1945
1946 // Mad Alchemist's Potion
1947 if (m_spellInfo->Id == 45051)
1948 {
1949 // find elixirs on target
1950 bool guardianFound = false;
1951 bool battleFound = false;
1953 for (Unit::AuraApplicationMap::iterator itr = Auras.begin(); itr != Auras.end(); ++itr)
1954 {
1955 SpellGroupSpecialFlags sFlag = sSpellMgr->GetSpellGroupSpecialFlags(itr->second->GetBase()->GetId());
1956 if (!guardianFound)
1958 guardianFound = true;
1959 if (!battleFound)
1961 battleFound = true;
1962 if (battleFound && guardianFound)
1963 break;
1964 }
1965
1966 // get all available elixirs by mask and spell level
1967 std::set<uint32> availableElixirs;
1968 if (!guardianFound)
1969 sSpellMgr->GetSetOfSpellsInSpellGroupWithFlag(1, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN, availableElixirs);
1970 if (!battleFound)
1971 sSpellMgr->GetSetOfSpellsInSpellGroupWithFlag(1, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE, availableElixirs);
1972 for (std::set<uint32>::iterator itr = availableElixirs.begin(); itr != availableElixirs.end();)
1973 {
1974 SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(*itr);
1975 if (spellInfo->SpellLevel < m_spellInfo->SpellLevel || spellInfo->SpellLevel > unitTarget->GetLevel())
1976 availableElixirs.erase(itr++);
1977 else
1978 ++itr;
1979 }
1980
1981 if (!availableElixirs.empty())
1982 {
1983 // cast random elixir on target
1985 }
1986 }
1987}
@ SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED
Definition SharedDefines.h:668
@ SPELLFAMILY_POTION
Definition SharedDefines.h:3807
SpellGroupSpecialFlags
Definition SpellMgr.h:334
@ SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE
Definition SpellMgr.h:336
@ SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN
Definition SpellMgr.h:337
void EnergizeBySpell(Unit *victim, uint32 SpellID, uint32 Damage, Powers powertype)
Definition Unit.cpp:11363
void SendSpellDamageImmune(Unit *target, uint32 spellId)
Definition Unit.cpp:6565
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition Containers.h:133

References CalculatePct(), Unit::CastSpell(), damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), Unit::GetAppliedAuras(), Unit::GetCreateMana(), Unit::GetLevel(), Unit::GetMaxPower(), GetSpellInfo(), Unit::HasActivePowerType(), SpellInfo::HasAttribute(), Unit::HasUnitState(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), m_caster, m_CastItem, m_spellInfo, MAX_POWERS, Acore::Containers::SelectRandomContainerElement(), Unit::SendSpellDamageImmune(), SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN, SPELLFAMILY_POTION, SpellInfo::SpellFamilyName, SpellInfo::SpellLevel, sSpellMgr, UNIT_STATE_ISOLATED, and unitTarget.

◆ EffectEnergizePct()

void Spell::EffectEnergizePct ( SpellEffIndex  effIndex)
1990{
1992 return;
1993
1994 if (!unitTarget)
1995 return;
1996 if (!unitTarget->IsAlive())
1997 return;
1998
1999 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
2000 return;
2001
2002 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
2003
2005 return;
2006
2007 uint32 maxPower = unitTarget->GetMaxPower(power);
2008 if (maxPower == 0)
2009 return;
2010
2011 uint32 gain = CalculatePct(maxPower, damage);
2013}

References CalculatePct(), damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), Unit::GetMaxPower(), Unit::HasActivePowerType(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), m_caster, m_spellInfo, MAX_POWERS, SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectEnvironmentalDMG()

void Spell::EffectEnvironmentalDMG ( SpellEffIndex  effIndex)
299{
301 return;
302
303 if (!unitTarget || !unitTarget->IsAlive())
304 return;
305
306 if (unitTarget->IsPlayer())
308 else
309 {
311
312 uint32 absorb = dmgInfo.GetAbsorb();
313 uint32 resist = dmgInfo.GetResist();
314 uint32 envDamage = dmgInfo.GetDamage();
315
316 Unit::DealDamageMods(unitTarget, envDamage, &absorb);
317 damage = envDamage;
318
320 }
321}
@ DAMAGE_FIRE
Definition Player.h:835
uint32 EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
Definition Player.cpp:764

References damage, DAMAGE_FIRE, Unit::DealDamageMods(), effectHandleMode, Player::EnvironmentalDamage(), DamageInfo::GetAbsorb(), DamageInfo::GetDamage(), DamageInfo::GetResist(), SpellInfo::GetSchoolMask(), Unit::IsAlive(), Object::IsPlayer(), m_caster, m_spellInfo, Unit::SendSpellNonMeleeDamageLog(), SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectFeedPet()

void Spell::EffectFeedPet ( SpellEffIndex  effIndex)
Todo:
: fix crash when a spell has two effects, both pointed at the same item target
4513{
4515 return;
4516
4517 Player* player = m_caster->ToPlayer();
4518 if (!player)
4519 return;
4520
4521 Item* foodItem = itemTarget;
4522 if (!foodItem)
4523 return;
4524
4525 Pet* pet = player->GetPet();
4526 if (!pet)
4527 return;
4528
4529 if (!pet->IsAlive())
4530 return;
4531
4532 int32 benefit = pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel);
4533 if (benefit <= 0)
4534 return;
4535
4536 ExecuteLogEffectDestroyItem(effIndex, foodItem->GetEntry());
4537
4538 uint32 count = 1;
4539 player->DestroyItemCount(foodItem, count, true);
4541
4542 m_caster->CastCustomSpell(pet, m_spellInfo->Effects[effIndex].TriggerSpell, &benefit, nullptr, nullptr, true);
4543}
void ExecuteLogEffectDestroyItem(uint8 effIndex, uint32 entry)
Definition Spell.cpp:5179

References Unit::CastCustomSpell(), Player::DestroyItemCount(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectDestroyItem(), Pet::GetCurrentFoodBenefitLevel(), Object::GetEntry(), Player::GetPet(), Item::GetTemplate(), Unit::IsAlive(), ItemTemplate::ItemLevel, itemTarget, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and Object::ToPlayer().

◆ EffectForceCast()

void Spell::EffectForceCast ( SpellEffIndex  effIndex)
997{
999 return;
1000
1001 if (!unitTarget)
1002 return;
1003
1004 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
1005
1006 // normal case
1007 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
1008
1009 if (!spellInfo)
1010 {
1011 LOG_ERROR("spells.effect", "Spell::EffectForceCast of spell {}: triggering unknown spell id {}", m_spellInfo->Id, triggered_spell_id);
1012 return;
1013 }
1014
1015 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_FORCE_CAST && damage)
1016 {
1017 switch (m_spellInfo->Id)
1018 {
1019 case 52588: // Skeletal Gryphon Escape
1020 case 48598: // Ride Flamebringer Cue
1022 break;
1023 case 52463: // Hide In Mine Car
1024 case 52349: // Overtake
1025 unitTarget->CastCustomSpell(unitTarget, spellInfo->Id, &damage, nullptr, nullptr, true, nullptr, nullptr, m_originalCasterGUID);
1026 return;
1027 case 72378: // Blood Nova
1028 case 73058: // Blood Nova
1029 m_caster->CastSpell(unitTarget, damage, true); // additional spell cast
1030 break;
1031 }
1032 }
1033
1034 CustomSpellValues values;
1035 // set basepoints for trigger with value effect
1037 {
1038 // maybe need to set value only when basepoints == 0?
1042 }
1043
1044 SpellCastTargets targets;
1045 targets.SetUnitTarget(m_caster);
1046
1047 unitTarget->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK);
1048}
@ SPELL_EFFECT_FORCE_CAST
Definition SharedDefines.h:929
@ SPELL_EFFECT_FORCE_CAST_WITH_VALUE
Definition SharedDefines.h:930
@ SPELLVALUE_BASE_POINT1
Definition SpellDefines.h:114
@ SPELLVALUE_BASE_POINT2
Definition SpellDefines.h:115
@ SPELLVALUE_BASE_POINT0
Definition SpellDefines.h:113
Definition SpellDefines.h:165
void AddSpellMod(SpellValueMod mod, int32 value)
Definition SpellDefines.h:167

References CustomSpellValues::AddSpellMod(), Unit::CastCustomSpell(), Unit::CastSpell(), damage, effectHandleMode, SpellInfo::Effects, SpellInfo::Id, LOG_ERROR, m_caster, m_originalCasterGUID, m_spellInfo, Unit::RemoveAura(), SpellCastTargets::SetUnitTarget(), SPELL_EFFECT_FORCE_CAST, SPELL_EFFECT_FORCE_CAST_WITH_VALUE, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, TRIGGERED_FULL_MASK, and unitTarget.

◆ EffectForceDeselect()

void Spell::EffectForceDeselect ( SpellEffIndex  effIndex)
4769{
4771 return;
4772
4773 // xinef: clear focus
4775
4777 data << m_caster->GetGUID();
4778
4780 Acore::MessageDistDelivererToHostile notifier(m_caster, &data, dist);
4781 Cell::VisitObjects(m_caster, notifier, dist);
4782
4783 // xinef: we should also force pets to remove us from current target
4784 Unit::AttackerSet attackerSet;
4785 for (Unit::AttackerSet::const_iterator itr = m_caster->getAttackers().begin(); itr != m_caster->getAttackers().end(); ++itr)
4786 if ((*itr)->IsCreature() && !(*itr)->CanHaveThreatList())
4787 attackerSet.insert(*itr);
4788
4789 for (Unit::AttackerSet::const_iterator itr = attackerSet.begin(); itr != attackerSet.end(); ++itr)
4790 (*itr)->AttackStop();
4791
4792 // Xinef: Mirror images code Initialize Images
4793 if (m_spellInfo->Id == 58836)
4794 {
4795 std::vector<Unit*> images;
4796 for (Unit::ControlSet::const_iterator itr = m_caster->m_Controlled.begin(); itr != m_caster->m_Controlled.end(); ++itr)
4797 if ((*itr)->GetEntry() == 31216 /*NPC_MIRROR_IMAGE*/)
4798 images.push_back(*itr);
4799
4800 if (images.empty())
4801 return;
4802
4803 UnitList targets;
4804 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, m_caster->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4807 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4808 {
4809 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4810 continue;
4811
4812 if (Spell* spell = (*iter)->GetCurrentSpell(CURRENT_GENERIC_SPELL))
4813 {
4814 if (spell->m_targets.GetUnitTargetGUID() == m_caster->GetGUID())
4815 {
4816 SpellInfo const* si = spell->GetSpellInfo();
4817 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->IsCreature())
4818 {
4819 Creature* c = (*iter)->ToCreature();
4820 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4821 continue;
4822 }
4823
4824 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4825 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4826 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4827 {
4828 // at least one effect truly targets an unit, interrupt the spell
4829 interrupt = true;
4830 break;
4831 }
4832
4833 if (interrupt)
4834 spell->m_targets.SetUnitTarget(images.at(urand(0, images.size() - 1)));
4835 }
4836 }
4837 }
4838 }
4839}
#define VISIBILITY_COMPENSATION
Definition ObjectDefines.h:26
@ CREATURE_ELITE_WORLDBOSS
Definition SharedDefines.h:2984
@ SPELL_ATTR6_IGNORE_PHASE_SHIFT
Definition SharedDefines.h:628
@ TARGET_OBJECT_TYPE_UNIT
Definition SpellInfo.h:102
@ TARGET_OBJECT_TYPE_UNIT_AND_DEST
Definition SpellInfo.h:103
std::list< Unit * > UnitList
Definition Unit.h:77
Definition GridNotifiers.h:852
bool IsDungeonBoss() const
Definition Creature.cpp:3178
ControlSet m_Controlled
Definition Unit.h:1993
void SendClearTarget()
Definition Unit.cpp:20174
@ SMSG_CLEAR_TARGET
Definition Opcodes.h:989
Definition GridNotifiers.h:134
Definition GridNotifiers.h:414
static void VisitObjects(WorldObject const *obj, T &visitor, float radius)
Definition CellImpl.h:165
uint32 rank
Definition CreatureData.h:206

References CREATURE_ELITE_WORLDBOSS, CURRENT_GENERIC_SPELL, effectHandleMode, SpellInfo::Effects, Unit::getAttackers(), Creature::GetCreatureTemplate(), Object::GetGUID(), WorldObject::GetVisibilityRange(), SpellInfo::HasAttribute(), SpellInfo::Id, Creature::IsDungeonBoss(), Unit::IsPet(), Creature::isWorldBoss(), m_caster, Unit::m_Controlled, m_spellInfo, MAX_SPELL_EFFECTS, CreatureTemplate::rank, Unit::SendClearTarget(), SMSG_CLEAR_TARGET, SPELL_ATTR6_IGNORE_PHASE_SHIFT, SPELL_EFFECT_HANDLE_HIT, TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST, Object::ToCreature(), UNIT_STATE_CASTING, urand(), VISIBILITY_COMPENSATION, and Cell::VisitObjects().

◆ EffectGameObjectDamage()

void Spell::EffectGameObjectDamage ( SpellEffIndex  effIndex)
5908{
5910 return;
5911
5912 if (!gameObjTarget)
5913 return;
5914
5915 Unit* caster = m_originalCaster;
5916 if (!caster)
5917 return;
5918
5919 FactionTemplateEntry const* casterFaction = caster->GetFactionTemplateEntry();
5921 // Do not allow to damage GO's of friendly factions (ie: Wintergrasp Walls/Ulduar Storm Beacons)
5922 if ((casterFaction && targetFaction && !casterFaction->IsFriendlyTo(*targetFaction)) || !targetFaction)
5924}
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
void ModifyHealth(int32 change, Unit *attackerOrHealer=nullptr, uint32 spellId=0)
Definition GameObject.cpp:2258
FactionTemplateEntry const * GetFactionTemplateEntry() const
Definition Unit.cpp:10104
Definition DBCStructure.h:939
bool IsFriendlyTo(FactionTemplateEntry const &entry) const
Definition DBCStructure.h:951

References damage, effectHandleMode, GAMEOBJECT_FACTION, gameObjTarget, Unit::GetFactionTemplateEntry(), GetSpellInfo(), Object::GetUInt32Value(), FactionTemplateEntry::IsFriendlyTo(), m_originalCaster, GameObject::ModifyHealth(), sFactionTemplateStore, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectGameObjectRepair()

void Spell::EffectGameObjectRepair ( SpellEffIndex  effIndex)

◆ EffectGameObjectSetDestructionState()

void Spell::EffectGameObjectSetDestructionState ( SpellEffIndex  effIndex)
5938{
5940 return;
5941
5943 return;
5944
5947}
GameObjectDestructibleState
Definition SharedDefines.h:1637
void SetDestructibleState(GameObjectDestructibleState state, Player *eventInvoker=nullptr, bool setHealth=false)
Definition GameObject.cpp:2321

References effectHandleMode, SpellInfo::Effects, gameObjTarget, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), m_originalCaster, m_spellInfo, GameObject::SetDestructibleState(), and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectHeal()

void Spell::EffectHeal ( SpellEffIndex  effIndex)
1473{
1475 return;
1476
1477 if (unitTarget && unitTarget->IsAlive() && damage >= 0)
1478 {
1479 // Try to get original caster
1481
1482 // Skip if m_originalCaster not available
1483 if (!caster)
1484 return;
1485
1486 int32 addhealth = damage;
1487
1488 // Vessel of the Naaru (Vial of the Sunwell trinket)
1489 if (m_spellInfo->Id == 45064)
1490 {
1491 // Amount of heal - depends from stacked Holy Energy
1492 int damageAmount = 0;
1493 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(45062, 0))
1494 {
1495 damageAmount += aurEff->GetAmount();
1497 }
1498
1499 addhealth += damageAmount;
1500 }
1501 // Swiftmend - consumes Regrowth or Rejuvenation
1503 {
1505 // find most short by duration
1506 AuraEffect* forcedTargetAura = nullptr;
1507 AuraEffect* targetAura = nullptr;
1508 for (Unit::AuraEffectList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)
1509 {
1510 if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_DRUID
1511 && (*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x50)
1512 {
1513 if (m_caster->GetGUID() == (*i)->GetCasterGUID())
1514 {
1515 if (!forcedTargetAura || (*i)->GetBase()->GetDuration() < forcedTargetAura->GetBase()->GetDuration())
1516 forcedTargetAura = *i;
1517 }
1518 else if (!targetAura || (*i)->GetBase()->GetDuration() < targetAura->GetBase()->GetDuration())
1519 targetAura = *i;
1520 }
1521 }
1522
1523 if (forcedTargetAura)
1524 targetAura = forcedTargetAura;
1525
1526 if (!targetAura)
1527 {
1528 LOG_ERROR("spells.effect", "Target({}) has aurastate AURA_STATE_SWIFTMEND but no matching aura.", unitTarget->GetGUID().ToString());
1529 return;
1530 }
1531
1532 int32 tickheal = targetAura->GetAmount();
1533 if (Unit* auraCaster = targetAura->GetCaster())
1534 tickheal = unitTarget->SpellHealingBonusTaken(auraCaster, targetAura->GetSpellInfo(), tickheal, DOT);
1535
1536 //int32 tickheal = targetAura->GetSpellInfo()->EffectBasePoints[idx] + 1;
1537 //It is said that talent bonus should not be included
1538
1539 int32 tickcount = 0;
1540 // Rejuvenation
1541 if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x10)
1542 tickcount = 4;
1543 // Regrowth
1544 else // if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x40)
1545 tickcount = 6;
1546
1547 addhealth += tickheal * tickcount;
1548
1549 // Glyph of Swiftmend
1550 if (!caster->HasAura(54824))
1551 unitTarget->RemoveAura(targetAura->GetId(), targetAura->GetCasterGUID());
1552
1553 //addhealth += tickheal * tickcount;
1554 //addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth, HEAL, unitTarget);
1555 }
1556 // Death Pact - return pct of max health to caster
1558 {
1559 addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, int32(caster->CountPctFromMaxHealth(damage)), HEAL, effIndex);
1560 addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
1561 }
1562 else if (m_spellInfo->Id != 33778) // not lifebloom
1563 {
1564 addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL, effIndex);
1565 addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
1566 }
1567
1568 // Implemented this way as there is no other way to do it currently (that I know :P)...
1569 if (caster->ToPlayer() && caster->HasAura(23401)) // Nefarian Corrupted Healing (priest)
1570 {
1572 {
1573 m_damage = 0;
1574 caster->CastSpell(unitTarget, 23402, false); // Nefarian Corrupted Healing Periodic Damage effect.
1575 return;
1576 }
1577 }
1578
1579 m_damage -= addhealth;
1580 }
1581}
@ SPELLFAMILY_DRUID
Definition SharedDefines.h:3801
@ SPELLFAMILY_DEATHKNIGHT
Definition SharedDefines.h:3809
@ AURA_STATE_SWIFTMEND
Definition SharedDefines.h:1318
@ SPELL_SCHOOL_MASK_HOLY
Definition SharedDefines.h:309
@ SPELL_AURA_PERIODIC_HEAL
Definition SpellAuraDefines.h:71
@ DOT
Definition Unit.h:251
SpellInfo const * GetSpellInfo() const
Definition SpellAuraEffects.h:54
uint32 GetId() const
Definition SpellAuraEffects.cpp:433
Unit * GetCaster() const
Definition SpellAuraEffects.h:47
Aura * GetBase() const
Definition SpellAuraEffects.h:49
ObjectGuid GetCasterGUID() const
Definition SpellAuraEffects.h:48
int32 GetAmount() const
Definition SpellAuraEffects.h:64
uint32 TargetAuraState
Definition SpellInfo.h:341
uint32 CountPctFromMaxHealth(int32 pct) const
Definition Unit.h:1046

References AURA_STATE_SWIFTMEND, Unit::CastSpell(), Unit::CountPctFromMaxHealth(), damage, DOT, effectHandleMode, AuraEffect::GetAmount(), Unit::GetAuraEffect(), Unit::GetAuraEffectsByType(), AuraEffect::GetBase(), AuraEffect::GetCaster(), AuraEffect::GetCasterGUID(), Aura::GetDuration(), Object::GetGUID(), AuraEffect::GetId(), SpellInfo::GetSchoolMask(), AuraEffect::GetSpellInfo(), SpellInfo::HasAura(), Unit::HasAura(), Unit::HasAuraState(), HEAL, SpellInfo::Id, Unit::IsAlive(), LOG_ERROR, m_caster, m_damage, m_originalCaster, m_originalCasterGUID, m_spellInfo, Unit::RemoveAura(), Unit::RemoveAurasDueToSpell(), SPELL_AURA_PERIODIC_HEAL, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_SCHOOL_MASK_HOLY, SPELLFAMILY_DEATHKNIGHT, SPELLFAMILY_DRUID, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, Unit::SpellHealingBonusDone(), Unit::SpellHealingBonusTaken(), SpellInfo::TargetAuraState, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectHealMaxHealth()

void Spell::EffectHealMaxHealth ( SpellEffIndex  effIndex)
3670{
3672 return;
3673
3674 if (!unitTarget || !unitTarget->IsAlive())
3675 return;
3676
3678 {
3680 return;
3681 }
3682
3683 int32 addhealth = 0;
3684
3685 // damage == 0 - heal for caster max health
3686 if (damage == 0)
3687 addhealth = m_caster->GetMaxHealth();
3688 else
3689 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
3690
3691 m_healing += addhealth;
3692}
uint32 GetMaxHealth() const
Definition Unit.h:1034

References damage, effectHandleMode, Unit::GetHealth(), Unit::GetMaxHealth(), GetSpellInfo(), Unit::HasUnitState(), Unit::IsAlive(), m_caster, m_healing, Unit::SendSpellDamageImmune(), SPELL_EFFECT_HANDLE_HIT_TARGET, UNIT_STATE_ISOLATED, and unitTarget.

◆ EffectHealMechanical()

void Spell::EffectHealMechanical ( SpellEffIndex  effIndex)

◆ EffectHealPct()

void Spell::EffectHealPct ( SpellEffIndex  effIndex)

◆ EffectHealthLeech()

void Spell::EffectHealthLeech ( SpellEffIndex  effIndex)
1619{
1621 return;
1622
1623 if (!unitTarget || !unitTarget->IsAlive() || damage < 0)
1624 return;
1625
1628
1629 LOG_DEBUG("spells.aura", "HealthLeech :{}", damage);
1630
1631 // xinef: handled in spell.cpp
1632 //float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1633
1634 m_damage += damage;
1635 // get max possible damage, don't count overkill for heal
1636 //uint32 healthGain = uint32(-unitTarget->GetHealthGain(-damage) * healMultiplier);
1637
1638 //if (m_caster->IsAlive())
1639 //{
1640 // healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL);
1641 // healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
1642
1643 // m_caster->HealBySpell(m_caster, m_spellInfo, uint32(healthGain));
1644 //}
1645}
uint32 SpellDamageBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack=1)
Definition Unit.cpp:11883
uint32 SpellDamageBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition Unit.cpp:11707

References damage, effectHandleMode, Unit::IsAlive(), LOG_DEBUG, m_caster, m_damage, m_spellInfo, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), and unitTarget.

◆ EffectInebriate()

void Spell::EffectInebriate ( SpellEffIndex  effIndex)
4477{
4479 return;
4480
4481 if (!unitTarget)
4482 return;
4483
4484 Player* player = unitTarget->ToPlayer();
4485 if (!player)
4486 {
4487 return;
4488 }
4489
4490 uint8 currentDrunk = player->GetDrunkValue();
4491 int32 drunkMod = damage;
4492
4493 if (drunkMod == 0)
4494 return;
4495
4496 // drunkMod may contain values ​​that are guaranteed to cause uint8 overflow/underflow (examples: 29690, 46874)
4497 // In addition, we would not want currentDrunk to become more than 100.
4498 // So before adding the values, let's check that everything is fine.
4499 if (drunkMod > 0 && drunkMod > static_cast<int32>(100 - currentDrunk))
4500 currentDrunk = 100;
4501 else if (drunkMod < 0 && drunkMod < static_cast<int32>(0 - currentDrunk))
4502 currentDrunk = 0;
4503 else
4504 currentDrunk += drunkMod; // Due to previous checks we can be sure that currentDrunk will not go beyond [0-100] range.
4505
4506 player->SetDrunkValue(currentDrunk, m_CastItem ? m_CastItem->GetEntry() : 0);
4507
4508 if (currentDrunk == 100 && roll_chance_i(25))
4509 player->CastSpell(player, 67468, false); // Drunken Vomit
4510}
uint8 GetDrunkValue() const
Definition Player.h:2178
void SetDrunkValue(uint8 newDrunkValue, uint32 itemId=0)
Definition Player.cpp:981

References Unit::CastSpell(), damage, effectHandleMode, Player::GetDrunkValue(), Object::GetEntry(), m_CastItem, roll_chance_i(), Player::SetDrunkValue(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectInstaKill()

void Spell::EffectInstaKill ( SpellEffIndex  effIndex)
275{
277 return;
278
279 if (!unitTarget || !unitTarget->IsAlive() || unitTarget->HasAura(27827)) // Spirit of redemption doesn't make you death, but can cause infinite loops
280 return;
281
282 if (unitTarget->IsPlayer())
284 return;
285
286 if (m_caster == unitTarget) // prevent interrupt message
287 finish();
288
289 WorldPacket data(SMSG_SPELLINSTAKILLLOG, 8 + 8 + 4);
290 data << m_caster->GetGUID();
291 data << unitTarget->GetGUID();
292 data << uint32(m_spellInfo->Id);
293 m_caster->SendMessageToSet(&data, true);
294
296}
@ CHEAT_GOD
Definition Player.h:995
@ SPELL_SCHOOL_MASK_NORMAL
Definition SharedDefines.h:308
static uint32 DealDamage(Unit *attacker, Unit *victim, uint32 damage, CleanDamage const *cleanDamage=nullptr, DamageEffectType damagetype=DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *spellProto=nullptr, bool durabilityLoss=true, bool allowGM=false, Spell const *spell=nullptr)
Definition Unit.cpp:825
@ SMSG_SPELLINSTAKILLLOG
Definition Opcodes.h:845

References CHEAT_GOD, Unit::DealDamage(), effectHandleMode, finish(), Player::GetCommandStatus(), Object::GetGUID(), Unit::GetHealth(), Unit::HasAura(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), m_caster, m_spellInfo, NODAMAGE, WorldObject::SendMessageToSet(), SMSG_SPELLINSTAKILLLOG, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_SCHOOL_MASK_NORMAL, Object::ToPlayer(), and unitTarget.

◆ EffectInterruptCast()

void Spell::EffectInterruptCast ( SpellEffIndex  effIndex)
Todo:
: not all spells that used this effect apply cooldown at school spells
3695{
3697 return;
3698
3699 if (!unitTarget || !unitTarget->IsAlive())
3700 return;
3701
3703 // also exist case: apply cooldown to interrupted cast only and to all spells
3704 // there is no CURRENT_AUTOREPEAT_SPELL spells that can be interrupted
3706 {
3708 {
3709 SpellInfo const* curSpellInfo = spell->m_spellInfo;
3710 // check if we can interrupt spell
3711 if ((spell->getState() == SPELL_STATE_CASTING
3712 || (spell->getState() == SPELL_STATE_PREPARING && spell->GetCastTime() > 0.0f))
3716 {
3717 if (m_originalCaster)
3718 {
3720 unitTarget->ProhibitSpellSchool(curSpellInfo->GetSchoolMask(), duration/*spellInfo->GetDuration()*/);
3721 }
3722 ExecuteLogEffectInterruptCast(effIndex, unitTarget, curSpellInfo->Id);
3724 }
3725 }
3726 }
3727}
@ CHANNEL_INTERRUPT_FLAG_INTERRUPT
Definition SpellDefines.h:37
@ SPELL_INTERRUPT_FLAG_INTERRUPT
Definition SpellDefines.h:29
#define CURRENT_FIRST_NON_MELEE_SPELL
Definition Unit.h:544
CurrentSpellTypes
Definition Unit.h:537
@ CURRENT_CHANNELED_SPELL
Definition Unit.h:540
@ CURRENT_AUTOREPEAT_SPELL
Definition Unit.h:541
uint32 ChannelInterruptFlags
Definition SpellInfo.h:355
uint32 InterruptFlags
Definition SpellInfo.h:353
void ExecuteLogEffectInterruptCast(uint8 effIndex, Unit *victim, uint32 spellId)
Definition Spell.cpp:5152
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true, bool bySelf=false)
Definition Unit.cpp:4113
int32 CalcSpellDuration(SpellInfo const *spellProto)
Definition Unit.cpp:14957
virtual void ProhibitSpellSchool(SpellSchoolMask, uint32)
Definition Unit.h:1505

References Unit::CalcSpellDuration(), CHANNEL_INTERRUPT_FLAG_INTERRUPT, SpellInfo::ChannelInterruptFlags, CURRENT_AUTOREPEAT_SPELL, CURRENT_CHANNELED_SPELL, CURRENT_FIRST_NON_MELEE_SPELL, CURRENT_GENERIC_SPELL, effectHandleMode, ExecuteLogEffectInterruptCast(), Unit::GetCurrentSpell(), SpellInfo::GetSchoolMask(), SpellInfo::Id, SpellInfo::InterruptFlags, Unit::InterruptSpell(), Unit::IsAlive(), m_originalCaster, m_spellInfo, Unit::ModSpellDuration(), SpellInfo::PreventionType, Unit::ProhibitSpellSchool(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_INTERRUPT_FLAG_INTERRUPT, SPELL_PREVENTION_TYPE_SILENCE, SPELL_STATE_CASTING, SPELL_STATE_PREPARING, and unitTarget.

◆ EffectJump()

void Spell::EffectJump ( SpellEffIndex  effIndex)
1070{
1072 return;
1073
1074 if (m_caster->IsInFlight())
1075 return;
1076
1077 if (!unitTarget)
1078 return;
1079
1080 float speedXY, speedZ;
1081 CalculateJumpSpeeds(effIndex, m_caster->GetExactDist2d(unitTarget), speedXY, speedZ);
1082 m_caster->GetMotionMaster()->MoveJump(*unitTarget, speedXY, speedZ);
1083
1084 if (m_caster->IsPlayer())
1085 {
1086 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1087 }
1088}
void MoveJump(Position const &pos, float speedXY, float speedZ, uint32 id=0)
Definition MotionMaster.h:229
void CalculateJumpSpeeds(uint8 i, float dist, float &speedxy, float &speedz)
Definition SpellEffects.cpp:1153
float GetExactDist2d(const float x, const float y) const
Definition Position.h:170

References CalculateJumpSpeeds(), effectHandleMode, Position::GetExactDist2d(), Unit::GetMotionMaster(), Unit::IsInFlight(), Object::IsPlayer(), m_caster, MotionMaster::MoveJump(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectJumpDest()

void Spell::EffectJumpDest ( SpellEffIndex  effIndex)
1091{
1093 return;
1094
1095 if (m_caster->IsInFlight())
1096 return;
1097
1098 if (!m_targets.HasDst() || m_caster->GetVehicle())
1099 return;
1100
1101 // Init dest coordinates
1102 float x, y, z;
1103 destTarget->GetPosition(x, y, z);
1104 // xinef: this can happen if MovePositionToFirstCollision detects that X, Y cords are invalid and returns prematurely
1105 if (!Acore::IsValidMapCoord(x, y, z) || z <= INVALID_HEIGHT)
1106 return;
1107
1108 float speedXY, speedZ;
1109 float dist = m_caster->GetExactDist2d(x, y);
1110 CalculateJumpSpeeds(effIndex, dist, speedXY, speedZ);
1111
1112 // Override, calculations are incorrect
1113 if (m_spellInfo->Id == 49376) // feral charge
1114 {
1115 speedXY = pow(speedZ * 10, 8);
1117
1118 if (Player* player = m_caster->ToPlayer())
1119 {
1120 player->SetCanTeleport(true);
1121 }
1122
1123 if (m_caster->IsPlayer())
1124 {
1125 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1126 }
1127
1128 return;
1129 }
1130
1131 if (m_spellInfo->Id == 57604) // death grip
1132 {
1133 speedZ = 3.0f;
1134 speedXY = 50.0f;
1135 }
1136
1137 // crash fix?
1138 if (speedXY < 1.0f)
1139 speedXY = 1.0f;
1140
1141 if (Player* player = m_caster->ToPlayer())
1142 {
1143 player->SetCanTeleport(true);
1144 }
1145 m_caster->GetMotionMaster()->MoveJump(x, y, z, speedXY, speedZ);
1146
1147 if (m_caster->IsPlayer())
1148 {
1149 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1150 }
1151}
#define INVALID_HEIGHT
Definition GridTerrainData.h:27
@ UNIT_FIELD_TARGET
Definition UpdateFields.h:92
ObjectGuid GetGuidValue(uint16 index) const
Definition Object.cpp:326
bool IsValidMapCoord(float c)
Definition GridDefines.h:210

References CalculateJumpSpeeds(), destTarget, effectHandleMode, Position::GetExactDist2d(), Object::GetGuidValue(), Unit::GetMotionMaster(), Position::GetPosition(), ObjectAccessor::GetUnit(), Unit::GetVehicle(), SpellCastTargets::HasDst(), SpellInfo::Id, INVALID_HEIGHT, Unit::IsInFlight(), Object::IsPlayer(), Acore::IsValidMapCoord(), m_caster, m_spellInfo, m_targets, MotionMaster::MoveJump(), SPELL_EFFECT_HANDLE_LAUNCH, sScriptMgr, Object::ToPlayer(), and UNIT_FIELD_TARGET.

◆ EffectKillCredit()

void Spell::EffectKillCredit ( SpellEffIndex  effIndex)
5700{
5702 return;
5703
5704 if (!unitTarget)
5705 return;
5706
5708 if (!player)
5709 {
5710 return;
5711 }
5712
5713 int32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5714 if (!creatureEntry)
5715 {
5716 if (m_spellInfo->Id == 42793) // Burn Body
5717 creatureEntry = 24008; // Fallen Combatant
5718 }
5719
5720 if (creatureEntry)
5721 player->RewardPlayerAndGroupAtEvent(creatureEntry, unitTarget);
5722}
void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject *pRewardSource)
Definition Player.cpp:12758

References effectHandleMode, SpellInfo::Effects, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), SpellInfo::Id, m_spellInfo, Player::RewardPlayerAndGroupAtEvent(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectKillCreditPersonal()

void Spell::EffectKillCreditPersonal ( SpellEffIndex  effIndex)
5686{
5688 return;
5689
5690 if (!unitTarget)
5691 return;
5692
5694 {
5695 player->KilledMonsterCredit(m_spellInfo->Effects[effIndex].MiscValue);
5696 }
5697}

References effectHandleMode, SpellInfo::Effects, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectKnockBack()

void Spell::EffectKnockBack ( SpellEffIndex  effIndex)
4973{
4975 return;
4976
4977 if (!unitTarget)
4978 return;
4979
4980 // Xinef: allow entry specific spells to skip those checks
4981 if (m_spellInfo->Effects[effIndex].TargetA.GetCheckType() != TARGET_CHECK_ENTRY && m_spellInfo->Effects[effIndex].TargetB.GetCheckType() != TARGET_CHECK_ENTRY)
4982 {
4984 return;
4985
4986 if (unitTarget->GetVehicle())
4987 return;
4988
4989 if (Creature* creatureTarget = unitTarget->ToCreature())
4990 if (creatureTarget->isWorldBoss() || creatureTarget->IsDungeonBoss() || creatureTarget->IsImmuneToKnockback() || unitTarget->ToCreature()->GetCreatureType() == CREATURE_TYPE_GIANT)
4991 return;
4992 }
4993
4994 // Spells with SPELL_EFFECT_KNOCK_BACK(like Thunderstorm) can't knoback target if target has ROOT
4996 return;
4997
4998 // Instantly interrupt non melee spells being casted
5001
5002 float ratio = 0.1f;
5003 float speedxy = float(m_spellInfo->Effects[effIndex].MiscValue) * ratio;
5004 float speedz = float(damage) * ratio;
5005 if (speedxy <= 0.1f && speedz <= 0.1f)
5006 return;
5007
5008 float x, y;
5009 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_KNOCK_BACK_DEST)
5010 {
5011 if (m_targets.HasDst())
5012 destTarget->GetPosition(x, y);
5013 else
5014 return;
5015 }
5016 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_KNOCK_BACK)
5017 {
5018 m_caster->GetPosition(x, y);
5019 }
5020
5021 unitTarget->KnockbackFrom(x, y, speedxy, speedz);
5022
5023 if (unitTarget->IsPlayer())
5024 {
5025 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5026 }
5027}
@ SPELL_EFFECT_KNOCK_BACK_DEST
Definition SharedDefines.h:933
@ CREATURE_TYPE_GIANT
Definition SharedDefines.h:2643
@ CREATURE_TYPE_BEAST
Definition SharedDefines.h:2639
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true, bool bySelf=false)
Definition Unit.cpp:4185
uint32 GetCreatureType() const
Definition Unit.cpp:15283
void KnockbackFrom(float x, float y, float speedXY, float speedZ)
Definition Unit.cpp:19240

References CREATURE_TYPE_BEAST, CREATURE_TYPE_GIANT, damage, destTarget, effectHandleMode, SpellInfo::Effects, Unit::GetCreatureType(), Position::GetPosition(), Unit::GetVehicle(), SpellCastTargets::HasDst(), Unit::HasUnitState(), Unit::InterruptNonMeleeSpells(), Unit::IsNonMeleeSpellCast(), Object::IsPlayer(), Unit::IsVehicle(), Unit::KnockbackFrom(), m_caster, m_spellInfo, m_targets, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_KNOCK_BACK_DEST, sScriptMgr, TARGET_CHECK_ENTRY, Object::ToCreature(), Object::ToPlayer(), UNIT_STATE_ROOT, and unitTarget.

◆ EffectLeap()

void Spell::EffectLeap ( SpellEffIndex  effIndex)
4699{
4701 return;
4702
4703 if (!unitTarget || unitTarget->IsInFlight())
4704 return;
4705
4706 if (!m_targets.HasDst())
4707 return;
4708
4709 Position dstpos = destTarget->GetPosition();
4711}
void NearTeleportTo(Position &pos, bool casting=false, bool vehicleTeleport=false, bool withPet=false, bool removeTransport=false)
Definition Unit.cpp:19809

References destTarget, effectHandleMode, Position::GetOrientation(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), SpellCastTargets::HasDst(), Unit::IsInFlight(), m_caster, m_targets, Unit::NearTeleportTo(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectLeapBack()

void Spell::EffectLeapBack ( SpellEffIndex  effIndex)
5030{
5032 return;
5033
5034 if (!unitTarget)
5035 return;
5036
5037 float speedxy = m_spellInfo->Effects[effIndex].MiscValue / 10.0f;
5038 float speedz = damage / 10.0f;
5039 //1891: Disengage
5041
5042 if (m_caster->IsPlayer())
5043 {
5044 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
5045 }
5046
5047 // xinef: changes fall time
5048 if (m_caster->IsPlayer())
5050}
@ SPELLFAMILY_HUNTER
Definition SharedDefines.h:3803
void JumpTo(float speedXY, float speedZ, bool forward=true)
Definition Unit.cpp:19354

References damage, effectHandleMode, SpellInfo::Effects, GameTime::GetGameTime(), Position::GetPositionZ(), Object::IsPlayer(), Unit::JumpTo(), m_caster, m_spellInfo, Player::SetFallInformation(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELLFAMILY_HUNTER, SpellInfo::SpellFamilyName, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectLearnPetSpell()

void Spell::EffectLearnPetSpell ( SpellEffIndex  effIndex)
3255{
3257 return;
3258
3259 if (!unitTarget)
3260 return;
3261
3262 if (unitTarget->ToPlayer())
3263 {
3264 EffectLearnSpell(effIndex);
3265 return;
3266 }
3267 Pet* pet = unitTarget->ToPet();
3268 if (!pet)
3269 return;
3270
3271 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].TriggerSpell);
3272 if (!learn_spellproto)
3273 return;
3274
3275 pet->learnSpell(learn_spellproto->Id);
3277 pet->GetOwner()->PetSpellInitialize();
3278}
bool learnSpell(uint32 spell_id)
Definition Pet.cpp:1915
void EffectLearnSpell(SpellEffIndex effIndex)
Definition SpellEffects.cpp:2541

References effectHandleMode, EffectLearnSpell(), SpellInfo::Effects, Pet::GetOwner(), SpellInfo::Id, Pet::learnSpell(), m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellMgr, Unit::ToPet(), Object::ToPlayer(), and unitTarget.

Referenced by EffectLearnSpell().

◆ EffectLearnSkill()

void Spell::EffectLearnSkill ( SpellEffIndex  effIndex)
2772{
2774 return;
2775
2776 if (!unitTarget->IsPlayer())
2777 return;
2778
2779 if (damage < 0)
2780 return;
2781
2782 uint32 skillid = m_spellInfo->Effects[effIndex].MiscValue;
2783 uint16 skillval = unitTarget->ToPlayer()->GetPureSkillValue(skillid);
2784 unitTarget->ToPlayer()->SetSkill(skillid, m_spellInfo->Effects[effIndex].CalcValue(), skillval ? skillval : 1, damage * 75);
2785}
uint16 GetPureSkillValue(uint32 skill) const
Definition Player.cpp:5551
void SetSkill(uint16 id, uint16 step, uint16 currVal, uint16 maxVal)
Definition Player.cpp:5365

References damage, effectHandleMode, SpellInfo::Effects, Player::GetPureSkillValue(), Object::IsPlayer(), m_spellInfo, Player::SetSkill(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectLearnSpell()

void Spell::EffectLearnSpell ( SpellEffIndex  effIndex)
2542{
2544 return;
2545
2546 if (!unitTarget)
2547 return;
2548
2549 if (!unitTarget->IsPlayer())
2550 {
2551 if (unitTarget->ToPet())
2552 EffectLearnPetSpell(effIndex);
2553 return;
2554 }
2555
2556 Player* player = unitTarget->ToPlayer();
2557
2558 uint32 spellToLearn = (m_spellInfo->Id == 483 || m_spellInfo->Id == 55884) ? damage : m_spellInfo->Effects[effIndex].TriggerSpell;
2559 player->learnSpell(spellToLearn);
2560
2561 LOG_DEBUG("spells.aura", "Spell: Player {} has learned spell {} from Npc {}",
2562 player->GetGUID().ToString(), spellToLearn, m_caster->GetGUID().ToString());
2563}
void learnSpell(uint32 spellId, bool temporary=false, bool learnFromSkill=false)
Definition Player.cpp:3316
void EffectLearnPetSpell(SpellEffIndex effIndex)
Definition SpellEffects.cpp:3254

References damage, effectHandleMode, EffectLearnPetSpell(), SpellInfo::Effects, Object::GetGUID(), SpellInfo::Id, Object::IsPlayer(), Player::learnSpell(), LOG_DEBUG, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

Referenced by EffectLearnPetSpell().

◆ EffectMilling()

void Spell::EffectMilling ( SpellEffIndex  effIndex)
5509{
5511 return;
5512
5513 if (!m_caster->IsPlayer())
5514 return;
5515
5516 Player* p_caster = m_caster->ToPlayer();
5518 return;
5519
5520 if (itemTarget->GetCount() < 5)
5521 return;
5522
5523 if (sWorld->getBoolConfig(CONFIG_SKILL_MILLING))
5524 {
5525 uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_INSCRIPTION);
5526 uint32 reqSkillValue = itemTarget->GetTemplate()->RequiredSkillRank;
5527 p_caster->UpdateGatherSkill(SKILL_INSCRIPTION, SkillValue, reqSkillValue);
5528 }
5529
5531}
@ LOOT_MILLING
Definition LootMgr.h:87
@ CONFIG_SKILL_MILLING
Definition WorldConfig.h:51
void SendLoot(ObjectGuid guid, LootType loot_type)
Definition Player.cpp:7848
bool UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator=1)
Definition PlayerUpdates.cpp:762

References CONFIG_SKILL_MILLING, effectHandleMode, Item::GetCount(), Object::GetGUID(), Player::GetPureSkillValue(), Item::GetTemplate(), ItemTemplate::HasFlag(), Object::IsPlayer(), ITEM_FLAG_IS_MILLABLE, itemTarget, LOOT_MILLING, m_caster, ItemTemplate::RequiredSkillRank, Player::SendLoot(), SKILL_INSCRIPTION, SPELL_EFFECT_HANDLE_HIT_TARGET, sWorld, Object::ToPlayer(), and Player::UpdateGatherSkill().

◆ EffectModifyThreatPercent()

void Spell::EffectModifyThreatPercent ( SpellEffIndex  effIndex)
5342{
5344 return;
5345
5346 if (!unitTarget)
5347 return;
5348
5350}
void ModifyThreatByPercent(Unit *victim, int32 percent)
Definition ThreatMgr.cpp:508
ThreatMgr & GetThreatMgr()
Definition Unit.h:900

References damage, effectHandleMode, Unit::GetThreatMgr(), m_caster, ThreatMgr::ModifyThreatByPercent(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectNULL()

void Spell::EffectNULL ( SpellEffIndex  effIndex)
239{
240 LOG_DEBUG("spells.aura", "WORLD: Spell Effect DUMMY");
241}

References LOG_DEBUG.

Referenced by EffectPull().

◆ EffectOpenLock()

void Spell::EffectOpenLock ( SpellEffIndex  effIndex)
Todo:
: Add script for spell 41920 - Filling, becouse server it freze when use this spell
2082{
2084 return;
2085
2086 if (!m_caster->IsPlayer())
2087 {
2088 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No Player Caster!");
2089 return;
2090 }
2091
2092 Player* player = m_caster->ToPlayer();
2093
2094 uint32 lockId = 0;
2095 ObjectGuid guid;
2096
2097 // Get lockId
2098 if (gameObjTarget)
2099 {
2100 GameObjectTemplate const* goInfo = gameObjTarget->GetGOInfo();
2101 // Arathi Basin banner opening. /// @todo: Verify correctness of this check
2102 if ((goInfo->type == GAMEOBJECT_TYPE_BUTTON && goInfo->button.noDamageImmune) ||
2103 (goInfo->type == GAMEOBJECT_TYPE_GOOBER && goInfo->goober.losOK))
2104 {
2105 //CanUseBattlegroundObject() already called in CheckCast()
2106 // in battleground check
2107 if (Battleground* bg = player->GetBattleground())
2108 {
2109 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2110 return;
2111 }
2112 }
2113 else if (goInfo->type == GAMEOBJECT_TYPE_FLAGSTAND)
2114 {
2115 //CanUseBattlegroundObject() already called in CheckCast()
2116 // in battleground check
2117 if (Battleground* bg = player->GetBattleground())
2118 {
2119 if (bg->GetBgTypeID(true) == BATTLEGROUND_EY)
2120 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2121 return;
2122 }
2123 }
2124 else if (m_spellInfo->Id == 1842 && gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_TRAP)
2125 {
2128 {
2130 }
2131 return;
2132 }
2134 // handle outdoor pvp object opening, return true if go was registered for handling
2135 // these objects must have been spawned by outdoorpvp!
2136 else if (gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_GOOBER && sOutdoorPvPMgr->HandleOpenGo(player, gameObjTarget))
2137 return;
2138 lockId = goInfo->GetLockId();
2139 guid = gameObjTarget->GetGUID();
2140 }
2141 else if (itemTarget)
2142 {
2143 lockId = itemTarget->GetTemplate()->LockID;
2144 guid = itemTarget->GetGUID();
2145 }
2146 else
2147 {
2148 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No GameObject/Item Target!");
2149 return;
2150 }
2151
2152 SkillType skillId = SKILL_NONE;
2153 int32 reqSkillValue = 0;
2154 int32 skillValue;
2155
2156 SpellCastResult res = CanOpenLock(effIndex, lockId, skillId, reqSkillValue, skillValue);
2157 if (res != SPELL_CAST_OK)
2158 {
2159 SendCastResult(res);
2160 return;
2161 }
2162
2163 if (gameObjTarget)
2164 SendLoot(guid, LOOT_SKINNING);
2165 else if (itemTarget)
2166 {
2168 if (Player* itemOwner = itemTarget->GetOwner())
2169 itemTarget->SetState(ITEM_CHANGED, itemOwner);
2170 }
2171
2172 // not allow use skill grow at item base open
2173 if (!m_CastItem && skillId != SKILL_NONE)
2174 {
2175 // update skill if really known
2176 if (uint32 pureSkillValue = player->GetPureSkillValue(skillId))
2177 {
2178 if (gameObjTarget)
2179 {
2180 // Allow one skill-up until respawned
2181 if (!gameObjTarget->IsInSkillupList(player->GetGUID()))
2182 {
2184 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2185 }
2186
2187 }
2188 else if (itemTarget)
2189 {
2190 // Do one skill-up
2191 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2192 }
2193 }
2194 }
2196}
@ GO_JUST_DEACTIVATED
Definition GameObject.h:113
@ ITEM_FIELD_FLAG_UNLOCKED
Definition ItemTemplate.h:111
@ ITEM_CHANGED
Definition Item.h:210
@ LOOT_SKINNING
Definition LootMgr.h:85
#define sOutdoorPvPMgr
Definition OutdoorPvPMgr.h:102
@ GAMEOBJECT_TYPE_BUTTON
Definition SharedDefines.h:1572
@ GAMEOBJECT_TYPE_FLAGSTAND
Definition SharedDefines.h:1595
@ GAMEOBJECT_TYPE_GOOBER
Definition SharedDefines.h:1581
@ BATTLEGROUND_EY
Definition SharedDefines.h:3753
@ ITEM_FIELD_FLAGS
Definition UpdateFields.h:42
Unit * GetOwner() const
Definition GameObject.cpp:1219
void AddToSkillupList(ObjectGuid playerGuid)
Definition GameObject.cpp:3049
bool IsInSkillupList(ObjectGuid playerGuid) const
Definition GameObject.cpp:3055
LootState getLootState() const
Definition GameObject.h:223
void SetLootState(LootState s, Unit *unit=nullptr)
Definition GameObject.cpp:2423
void SetState(ItemUpdateState state, Player *forplayer=nullptr)
Definition Item.cpp:714
Definition Object.h:104
void ExecuteLogEffectOpenLock(uint8 effIndex, Object *obj)
Definition Spell.cpp:5167
void SendLoot(ObjectGuid guid, LootType loottype)
Definition SpellEffects.cpp:2015
Definition GameObjectData.h:31
struct GameObjectTemplate::@232::@243 goober
uint32 GetAutoCloseTime() const
Definition GameObjectData.h:510
struct GameObjectTemplate::@232::@235 button
uint32 noDamageImmune
Definition GameObjectData.h:48
uint32 losOK
Definition GameObjectData.h:64
uint32 GetLockId() const
Definition GameObjectData.h:427

References GameObject::AddToSkillupList(), BATTLEGROUND_EY, GameObjectTemplate::button, CanOpenLock(), effectHandleMode, ExecuteLogEffectOpenLock(), GAMEOBJECT_TYPE_BUTTON, GAMEOBJECT_TYPE_FLAGSTAND, GAMEOBJECT_TYPE_GOOBER, GAMEOBJECT_TYPE_TRAP, gameObjTarget, GameObjectTemplate::GetAutoCloseTime(), Player::GetBattleground(), GameObject::GetGOInfo(), Object::GetGUID(), GameObjectTemplate::GetLockId(), GameObject::getLootState(), GameObject::GetOwner(), Item::GetOwner(), Player::GetPureSkillValue(), Item::GetTemplate(), GO_JUST_DEACTIVATED, GameObjectTemplate::goober, SpellInfo::Id, IN_MILLISECONDS, GameObject::IsInSkillupList(), Object::IsPlayer(), ITEM_CHANGED, ITEM_FIELD_FLAG_UNLOCKED, ITEM_FIELD_FLAGS, itemTarget, ItemTemplate::LockID, LOG_DEBUG, LOOT_SKINNING, GameObjectTemplate::losOK, m_caster, m_CastItem, m_spellInfo, GameObjectTemplate::noDamageImmune, SendCastResult(), SendLoot(), Object::SetFlag(), GameObject::SetLootState(), GameObject::SetRespawnTime(), Item::SetState(), SKILL_NONE, sOutdoorPvPMgr, SPELL_CAST_OK, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), GameObjectTemplate::type, and Player::UpdateGatherSkill().

◆ EffectParry()

void Spell::EffectParry ( SpellEffIndex  effIndex)
4681{
4683 return;
4684
4685 if (m_caster->IsPlayer())
4686 m_caster->ToPlayer()->SetCanParry(true);
4687}
void SetCanParry(bool value)
Definition Player.cpp:13149

References effectHandleMode, Object::IsPlayer(), m_caster, Player::SetCanParry(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectPersistentAA()

void Spell::EffectPersistentAA ( SpellEffIndex  effIndex)
1845{
1847 return;
1848
1849 if (!m_spellAura)
1850 {
1852 float radius = m_spellInfo->Effects[effIndex].CalcRadius(caster);
1853
1854 // Caster not in world, might be spell triggered from aura removal
1855 if (!caster->IsInWorld() || !caster->FindMap() || !ObjectAccessor::GetUnit(*caster, caster->GetGUID())) // pussywizard: temporary crash fix (FindMap and GetUnit are mine)
1856 return;
1857 DynamicObject* dynObj = new DynamicObject();
1859 {
1860 delete dynObj;
1861 return;
1862 }
1863
1865 {
1866 m_spellAura = aura;
1869 }
1870 else
1871 return;
1872 }
1873
1876}
#define MAX_EFFECT_MASK
Definition DBCStructure.h:1639
@ DYNAMIC_OBJECT_AREA_SPELL
Definition DynamicObject.h:30
DynamicObject * GetDynobjOwner() const
Definition SpellAuras.h:109
static Aura * TryCreate(SpellInfo const *spellproto, uint8 effMask, WorldObject *owner, Unit *caster, int32 *baseAmount=nullptr, Item *castItem=nullptr, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemGUID=ObjectGuid::Empty)
Definition SpellAuras.cpp:352

References Aura::_ApplyEffectForTargets(), Aura::_RegisterForTargets(), ASSERT, DynamicObject::CreateDynamicObject(), destTarget, DYNAMIC_OBJECT_AREA_SPELL, DynamicObject, SpellValue::EffectBasePoints, effectHandleMode, SpellInfo::Effects, WorldObject::FindMap(), Map::GenerateLowGuid(), Aura::GetDynobjOwner(), Object::GetEntry(), Object::GetGUID(), WorldObject::GetMap(), ObjectAccessor::GetUnit(), SpellInfo::Id, Object::IsInWorld(), m_caster, m_originalCaster, m_spellAura, m_spellInfo, m_spellValue, m_triggeredByAuraSpell, MAX_EFFECT_MASK, Aura::SetTriggeredByAuraSpellInfo(), SPELL_EFFECT_HANDLE_HIT, TriggeredByAuraSpellData::spellInfo, Aura::TryCreate(), and WORLD_TRIGGER.

◆ EffectPickPocket()

void Spell::EffectPickPocket ( SpellEffIndex  effIndex)

◆ EffectPlayMusic()

void Spell::EffectPlayMusic ( SpellEffIndex  effIndex)
6099{
6101 return;
6102
6103 if (!unitTarget)
6104 return;
6105
6106 Player* player = unitTarget->ToPlayer();
6107 if (!player)
6108 {
6109 return;
6110 }
6111
6112 uint32 soundid = m_spellInfo->Effects[effIndex].MiscValue;
6113
6114 if (!sSoundEntriesStore.LookupEntry(soundid))
6115 {
6116 LOG_ERROR("spells.effect", "EffectPlayMusic: Sound (Id: {}) not exist in spell {}.", soundid, m_spellInfo->Id);
6117 return;
6118 }
6119
6121}
DBCStorage< SoundEntriesEntry > sSoundEntriesStore(SoundEntriesfmt)
Definition MiscPackets.h:58

References effectHandleMode, SpellInfo::Effects, SpellInfo::Id, LOG_ERROR, m_spellInfo, Player::SendDirectMessage(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSoundEntriesStore, Object::ToPlayer(), and unitTarget.

◆ EffectPlaySound()

void Spell::EffectPlaySound ( SpellEffIndex  effIndex)
6152{
6154 return;
6155
6156 if (!unitTarget)
6157 return;
6158
6159 Player* player = unitTarget->ToPlayer();
6160 if (!player)
6161 {
6162 return;
6163 }
6164
6165 switch (m_spellInfo->Id)
6166 {
6167 case 58730: // Restricted Flight Area
6168 case 58600: // Restricted Flight Area
6170 break;
6171 default:
6172 break;
6173 }
6174
6175 uint32 soundId = m_spellInfo->Effects[effIndex].MiscValue;
6176
6177 if (!sSoundEntriesStore.LookupEntry(soundId))
6178 {
6179 LOG_ERROR("spells.effect", "EffectPlayerSound: Sound (Id: {}) not exist in spell {}.", soundId, m_spellInfo->Id);
6180 return;
6181 }
6182
6183 player->PlayDirectSound(soundId, player);
6184}
@ LANG_ZONE_NOFLYZONE
Definition Language.h:759
Definition Chat.h:37
void SendNotification(std::string_view str)
Definition Chat.cpp:105
void PlayDirectSound(uint32 sound_id, Player *target=nullptr)
Definition Object.cpp:2883

References effectHandleMode, SpellInfo::Effects, Player::GetSession(), SpellInfo::Id, LANG_ZONE_NOFLYZONE, LOG_ERROR, m_spellInfo, WorldObject::PlayDirectSound(), ChatHandler::SendNotification(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSoundEntriesStore, Object::ToPlayer(), and unitTarget.

◆ EffectPowerBurn()

void Spell::EffectPowerBurn ( SpellEffIndex  effIndex)
1431{
1433 return;
1434
1435 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1436 return;
1437
1438 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1439
1441 return;
1442
1443 // burn x% of target's mana, up to maximum of 2x% of caster's mana (Mana Burn)
1444 if (m_spellInfo->Id == 8129)
1445 {
1448 damage = std::min(damage, maxDamage);
1449
1450 // Remove fear
1452 }
1453
1454 int32 power = damage;
1455 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1456 if (PowerType == POWER_MANA)
1457 power -= unitTarget->GetSpellCritDamageReduction(power);
1458
1459 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -power));
1460
1461 // NO - Not a typo - EffectPowerBurn uses effect value multiplier - not effect damage multiplier
1462 float dmgMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1463
1464 // add log data before multiplication (need power amount, not damage)
1465 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, 0.0f);
1466
1467 newDamage = int32(newDamage * dmgMultiplier);
1468
1469 m_damage += newDamage;
1470}
void ExecuteLogEffectTakeTargetPower(uint8 effIndex, Unit *target, uint32 PowerType, uint32 powerTaken, float gainMultiplier)
Definition Spell.cpp:5136
int32 ModifyPower(Powers power, int32 val, bool withPowerUpdate=true)
Definition Unit.cpp:14250
uint32 GetSpellCritDamageReduction(uint32 damage) const
Definition Unit.h:1205

References CalculatePct(), damage, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectTakeTargetPower(), Unit::GetMaxPower(), Unit::GetSpellCritDamageReduction(), Unit::HasActivePowerType(), SpellInfo::Id, Unit::IsAlive(), m_caster, m_damage, m_originalCaster, m_spellInfo, MAX_POWERS, Unit::ModifyPower(), POWER_MANA, Unit::RemoveAurasByType(), SPELL_AURA_MOD_FEAR, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectPowerDrain()

void Spell::EffectPowerDrain ( SpellEffIndex  effIndex)
1352{
1354 return;
1355
1356 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1357 return;
1358
1359 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1360
1362 return;
1363
1364 // add spell damage bonus
1367
1368 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1369 int32 power = damage;
1370 if (PowerType == POWER_MANA)
1371 power -= unitTarget->GetSpellCritDamageReduction(power);
1372
1373 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -int32(power)));
1374
1375 float gainMultiplier = 0.0f;
1376
1377 // Don`t restore from self drain
1378 if (m_caster != unitTarget)
1379 {
1380 gainMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1381
1382 int32 gain = int32(newDamage * gainMultiplier);
1383
1385 }
1386 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, gainMultiplier);
1387}

References damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), ExecuteLogEffectTakeTargetPower(), Unit::GetSpellCritDamageReduction(), Unit::HasActivePowerType(), SpellInfo::Id, Unit::IsAlive(), m_caster, m_originalCaster, m_spellInfo, MAX_POWERS, Unit::ModifyPower(), POWER_MANA, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), and unitTarget.

◆ EffectProficiency()

void Spell::EffectProficiency ( SpellEffIndex  effIndex)
2308{
2310 return;
2311
2312 if (!m_caster->IsPlayer())
2313 return;
2314 Player* p_target = m_caster->ToPlayer();
2315
2317 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && !(p_target->GetWeaponProficiency() & subClassMask))
2318 {
2319 p_target->AddWeaponProficiency(subClassMask);
2321 }
2322 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR && !(p_target->GetArmorProficiency() & subClassMask))
2323 {
2324 p_target->AddArmorProficiency(subClassMask);
2326 }
2327}
uint32 GetArmorProficiency() const
Definition Player.h:1366
void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask)
Definition Player.cpp:10148
uint32 GetWeaponProficiency() const
Definition Player.h:1365
void AddArmorProficiency(uint32 newflag)
Definition Player.h:1364
void AddWeaponProficiency(uint32 newflag)
Definition Player.h:1363
int32 EquippedItemSubClassMask
Definition SpellInfo.h:377

References Player::AddArmorProficiency(), Player::AddWeaponProficiency(), effectHandleMode, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, Player::GetArmorProficiency(), Player::GetWeaponProficiency(), Object::IsPlayer(), ITEM_CLASS_ARMOR, ITEM_CLASS_WEAPON, m_caster, m_spellInfo, Player::SendProficiency(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectProspecting()

void Spell::EffectProspecting ( SpellEffIndex  effIndex)

◆ EffectPull()

void Spell::EffectPull ( SpellEffIndex  effIndex)
Todo:
: create a proper pull towards distract spell center for distract
2684{
2686 EffectNULL(effIndex);
2687}
void EffectNULL(SpellEffIndex effIndex)
Definition SpellEffects.cpp:238

References EffectNULL().

◆ EffectPullTowards()

void Spell::EffectPullTowards ( SpellEffIndex  effIndex)
5115{
5117 return;
5118
5119 if (!unitTarget)
5120 return;
5121
5122 Position pos;
5123 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_PULL_TOWARDS_DEST)
5124 {
5125 if (m_targets.HasDst())
5126 pos.Relocate(*destTarget);
5127 else
5128 return;
5129 }
5130 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_PULL_TOWARDS)
5131 {
5132 // Xinef: Increase Z position a little bit, should protect from falling through textures
5134 }
5135
5136 float speedXY = float(m_spellInfo->Effects[effIndex].MiscValue) ? float(m_spellInfo->Effects[effIndex].MiscValue) * 0.1f : 30.f;
5137 float speedZ = unitTarget->GetDistance(pos) / speedXY * 0.5f * Movement::gravity;
5138
5139 unitTarget->GetMotionMaster()->MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), speedXY, speedZ);
5140
5141 if (unitTarget->IsPlayer())
5142 {
5143 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5144 }
5145}
@ SPELL_EFFECT_PULL_TOWARDS_DEST
Definition SharedDefines.h:934
void Relocate(float x, float y)
Definition Position.h:77

References destTarget, effectHandleMode, SpellInfo::Effects, WorldObject::GetDistance(), Unit::GetMotionMaster(), Position::GetOrientation(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Movement::gravity, SpellCastTargets::HasDst(), Object::IsPlayer(), m_caster, m_spellInfo, m_targets, MotionMaster::MoveJump(), Position::Relocate(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_PULL_TOWARDS_DEST, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectQuestClear()

void Spell::EffectQuestClear ( SpellEffIndex  effIndex)
5053{
5055 return;
5056
5057 if (!unitTarget)
5058 return;
5059
5060 Player* player = unitTarget->ToPlayer();
5061 if (!player)
5062 {
5063 return;
5064 }
5065
5066 uint32 quest_id = m_spellInfo->Effects[effIndex].MiscValue;
5067
5068 Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id);
5069
5070 if (!quest)
5071 return;
5072
5073 // Player has never done this quest
5074 if (player->GetQuestStatus(quest_id) == QUEST_STATUS_NONE)
5075 return;
5076
5077 // remove all quest entries for 'entry' from quest log
5078 for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot)
5079 {
5080 uint32 logQuest = player->GetQuestSlotQuestId(slot);
5081 if (logQuest == quest_id)
5082 {
5083 player->SetQuestSlot(slot, 0);
5084
5085 // we ignore unequippable quest items in this case, it's still be equipped
5086 player->TakeQuestSourceItem(logQuest, false);
5087
5088 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
5089 {
5090 player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest();
5091 player->UpdatePvPState();
5092 }
5093 }
5094 }
5095
5096 player->RemoveRewardedQuest(quest_id);
5097 player->RemoveActiveQuest(quest_id, false);
5098}
@ QUEST_FLAGS_FLAGS_PVP
Definition QuestDef.h:145
#define MAX_QUEST_LOG_SIZE
Definition QuestDef.h:33
@ QUEST_STATUS_NONE
Definition QuestDef.h:100
bool HasPvPForcingQuest() const
Definition PlayerQuest.cpp:2495
void UpdatePvPState()
Definition PlayerUpdates.cpp:1440
uint32 GetQuestSlotQuestId(uint16 slot) const
Definition Player.h:1488
void SetQuestSlot(uint16 slot, uint32 quest_id, uint32 timer=0)
Definition Player.h:1492
PvPInfo pvpInfo
Definition Player.h:1849
bool TakeQuestSourceItem(uint32 questId, bool msg)
Definition PlayerQuest.cpp:1363
void RemoveActiveQuest(uint32 questId, bool update=true)
Definition PlayerQuest.cpp:1495
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition PlayerQuest.cpp:1430
void RemoveRewardedQuest(uint32 questId, bool update=true)
Definition PlayerQuest.cpp:1513
Definition QuestDef.h:210
bool HasFlag(uint32 flag) const
Definition QuestDef.h:221
bool IsHostile
Definition Player.h:355
bool IsInHostileArea
Definition Player.h:356

References effectHandleMode, SpellInfo::Effects, Player::GetQuestSlotQuestId(), Player::GetQuestStatus(), Quest::HasFlag(), Player::HasPvPForcingQuest(), PvPInfo::IsHostile, PvPInfo::IsInHostileArea, m_spellInfo, MAX_QUEST_LOG_SIZE, Player::pvpInfo, QUEST_FLAGS_FLAGS_PVP, QUEST_STATUS_NONE, Player::RemoveActiveQuest(), Player::RemoveRewardedQuest(), Player::SetQuestSlot(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Player::TakeQuestSourceItem(), Object::ToPlayer(), unitTarget, and Player::UpdatePvPState().

◆ EffectQuestComplete()

void Spell::EffectQuestComplete ( SpellEffIndex  effIndex)
4740{
4742 return;
4743
4744 if (!unitTarget)
4745 return;
4746
4747 Player* player = unitTarget->ToPlayer();
4748 if (!player)
4749 {
4750 return;
4751 }
4752
4753 uint32 questId = m_spellInfo->Effects[effIndex].MiscValue;
4754 if (questId)
4755 {
4756 Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
4757 if (!quest)
4758 return;
4759
4760 uint16 logSlot = player->FindQuestSlot(questId);
4761 if (logSlot < MAX_QUEST_LOG_SIZE)
4762 player->AreaExploredOrEventHappens(questId);
4763 else if (player->CanTakeQuest(quest, false)) // Check if the quest has already been turned in.
4764 player->SetRewardedQuest(questId); // If not, set status to rewarded without broadcasting it to client.
4765 }
4766}
uint16 FindQuestSlot(uint32 quest_id) const
Definition PlayerQuest.cpp:1782
bool CanTakeQuest(Quest const *quest, bool msg)
Definition PlayerQuest.cpp:251
void SetRewardedQuest(uint32 quest_id)
Definition PlayerQuest.cpp:880
void AreaExploredOrEventHappens(uint32 questId)
Definition PlayerQuest.cpp:1791

References Player::AreaExploredOrEventHappens(), Player::CanTakeQuest(), effectHandleMode, SpellInfo::Effects, Player::FindQuestSlot(), m_spellInfo, MAX_QUEST_LOG_SIZE, Player::SetRewardedQuest(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectQuestFail()

void Spell::EffectQuestFail ( SpellEffIndex  effIndex)
5725{
5727 return;
5728
5729 if (!unitTarget)
5730 return;
5731
5732 if (Player* player = unitTarget->ToPlayer())
5733 {
5734 player->FailQuest(m_spellInfo->Effects[effIndex].MiscValue);
5735 }
5736}

References effectHandleMode, SpellInfo::Effects, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectQuestStart()

void Spell::EffectQuestStart ( SpellEffIndex  effIndex)
5739{
5741 return;
5742
5743 if (!unitTarget)
5744 return;
5745
5746 Player* player = unitTarget->ToPlayer();
5747 if (!player)
5748 return;
5749
5750 if (Quest const* quest = sObjectMgr->GetQuestTemplate(m_spellInfo->Effects[effIndex].MiscValue))
5751 {
5752 if (!player->CanTakeQuest(quest, false))
5753 return;
5754
5755 if (quest->IsAutoAccept() && player->CanAddQuest(quest, false))
5756 player->AddQuestAndCheckCompletion(quest, player);
5757
5758 player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true);
5759 }
5760}
void SendQuestGiverQuestDetails(Quest const *quest, ObjectGuid npcGUID, bool activateAccept) const
Definition GossipDef.cpp:388
bool CanAddQuest(Quest const *quest, bool msg)
Definition PlayerQuest.cpp:264
void AddQuestAndCheckCompletion(Quest const *quest, Object *questGiver)
Definition PlayerQuest.cpp:421
PlayerMenu * PlayerTalkClass
Definition Player.h:2250

References Player::AddQuestAndCheckCompletion(), Player::CanAddQuest(), Player::CanTakeQuest(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), m_spellInfo, Player::PlayerTalkClass, PlayerMenu::SendQuestGiverQuestDetails(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectRechargeManaGem()

void Spell::EffectRechargeManaGem ( SpellEffIndex  effIndex)
6241{
6243 return;
6244
6245 if (!unitTarget || !unitTarget->IsPlayer())
6246 return;
6247
6248 Player* player = m_caster->ToPlayer();
6249
6250 if (!player)
6251 return;
6252
6253 uint32 item_id = m_spellInfo->Effects[EFFECT_0].ItemType;
6254
6255 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
6256 if (!pProto)
6257 {
6258 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
6259 return;
6260 }
6261
6262 if (Item* pItem = player->GetItemByEntry(item_id))
6263 {
6264 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
6265 pItem->SetSpellCharges(x, pProto->Spells[x].SpellCharges);
6266 pItem->SetState(ITEM_CHANGED, player);
6267 }
6268}

References EFFECT_0, effectHandleMode, SpellInfo::Effects, EQUIP_ERR_ITEM_NOT_FOUND, Player::GetItemByEntry(), Object::IsPlayer(), ITEM_CHANGED, m_caster, m_spellInfo, MAX_ITEM_PROTO_SPELLS, Player::SendEquipError(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, _Spell::SpellCharges, ItemTemplate::Spells, Object::ToPlayer(), and unitTarget.

◆ EffectRedirectThreat()

void Spell::EffectRedirectThreat ( SpellEffIndex  effIndex)
5899{
5901 return;
5902
5903 if (unitTarget)
5905}
void SetRedirectThreat(ObjectGuid guid, uint32 pct)
Definition Unit.h:907

References damage, effectHandleMode, Object::GetGUID(), m_caster, Unit::SetRedirectThreat(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectRemoveAura()

void Spell::EffectRemoveAura ( SpellEffIndex  effIndex)
6187{
6189 return;
6190
6191 if (!unitTarget)
6192 return;
6193 // there may be need of specifying casterguid of removed auras
6194 unitTarget->RemoveAurasDueToSpell(m_spellInfo->Effects[effIndex].TriggerSpell);
6195}

References effectHandleMode, SpellInfo::Effects, m_spellInfo, Unit::RemoveAurasDueToSpell(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectRenamePet()

void Spell::EffectRenamePet ( SpellEffIndex  effIndex)
6087{
6089 return;
6090
6091 if (!unitTarget || !unitTarget->IsCreature() ||
6093 return;
6094
6096}
@ UNIT_CAN_BE_RENAMED
Definition UnitDefines.h:149
@ UNIT_FIELD_BYTES_2
Definition UpdateFields.h:161
void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition Object.cpp:900
PetType getPetType() const
Definition Pet.h:52

References effectHandleMode, Pet::getPetType(), HUNTER_PET, Object::IsCreature(), Unit::IsPet(), Object::SetByteFlag(), SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), UNIT_CAN_BE_RENAMED, UNIT_FIELD_BYTES_2, and unitTarget.

◆ EffectReputation()

void Spell::EffectReputation ( SpellEffIndex  effIndex)
4714{
4716 return;
4717
4718 if (!unitTarget)
4719 return;
4720
4721 Player* player = unitTarget->ToPlayer();
4722 if (!player)
4723 {
4724 return;
4725 }
4726
4727 float repChange = static_cast<float>(damage);
4728
4729 uint32 factionId = m_spellInfo->Effects[effIndex].MiscValue;
4730
4731 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
4732 if (!factionEntry)
4733 return;
4734
4735 repChange = player->CalculateReputationGain(REPUTATION_SOURCE_SPELL, 0, repChange, factionId);
4736 player->GetReputationMgr().ModifyReputation(factionEntry, repChange);
4737}
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
@ REPUTATION_SOURCE_SPELL
Definition SharedDefines.h:198
float CalculateReputationGain(ReputationSource source, uint32 creatureOrQuestLevel, float rep, int32 faction, bool noQuestBonus=false)
Definition Player.cpp:5905
ReputationMgr & GetReputationMgr()
Definition Player.h:2132
bool ModifyReputation(FactionEntry const *factionEntry, float standing, bool noSpillOver=false, Optional< ReputationRank > repMaxCap={})
Definition ReputationMgr.h:117
Definition DBCStructure.h:907

References Player::CalculateReputationGain(), damage, effectHandleMode, SpellInfo::Effects, Player::GetReputationMgr(), m_spellInfo, ReputationMgr::ModifyReputation(), REPUTATION_SOURCE_SPELL, sFactionStore, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectResurrect()

void Spell::EffectResurrect ( SpellEffIndex  effIndex)
4632{
4634 return;
4635
4636 if (!unitTarget)
4637 return;
4638
4639 if (!unitTarget)
4640 return;
4641
4642 Player* target = unitTarget->ToPlayer();
4643 if (!target)
4644 {
4645 return;
4646 }
4647
4648 if (unitTarget->IsAlive() || !unitTarget->IsInWorld())
4649 return;
4650
4651 if (target->isResurrectRequested()) // already have one active request
4652 return;
4653
4654 uint32 health = target->CountPctFromMaxHealth(damage);
4656
4657 ExecuteLogEffectResurrect(effIndex, target);
4658
4660 SendResurrectRequest(target);
4661}
void setResurrectRequestData(ObjectGuid guid, uint32 mapId, float X, float Y, float Z, uint32 health, uint32 mana)
Definition Player.h:1818
bool isResurrectRequested() const
Definition Player.h:1830
void ExecuteLogEffectResurrect(uint8 effIndex, Unit *target)
Definition Spell.cpp:5197
void SendResurrectRequest(Player *target)
Definition Spell.cpp:5259

References CalculatePct(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, ExecuteLogEffectResurrect(), Object::GetGUID(), WorldLocation::GetMapId(), Unit::GetMaxPower(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::IsAlive(), Object::IsInWorld(), Player::isResurrectRequested(), m_caster, POWER_MANA, SendResurrectRequest(), Player::setResurrectRequestData(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectResurrectNew()

◆ EffectResurrectPet()

void Spell::EffectResurrectPet ( SpellEffIndex  effIndex)
Todo:
: Better to fail Hunter's "Revive Pet" at cast instead of here when casting ends
5191{
5193 return;
5194
5195 if (damage < 0)
5196 return;
5197
5198 Player* player = m_caster->ToPlayer();
5199 if (!player)
5200 {
5201 return;
5202 }
5203
5204 Pet* pet = player->GetPet();
5205 if (!pet)
5206 {
5207 // Position passed to SummonPet is irrelevant with current implementation,
5208 // pet will be relocated without using these coords in Pet::LoadPetFromDB
5209 player->SummonPet(0, 0.0f, 0.0f, 0.0f, 0.0f, SUMMON_PET, 0s, damage);
5210 return;
5211 }
5212
5214 if (pet->IsAlive())
5215 {
5216 return;
5217 }
5218
5219 // Reposition the pet's corpse before reviving so as not to grab aggro
5220 // We can use a different, more accurate version of GetClosePoint() since we have a pet
5221 float x, y, z; // Will be used later to reposition the pet if we have one
5222 player->GetClosePoint(x, y, z, pet->GetCombatReach(), PET_FOLLOW_DIST, pet->GetFollowAngle());
5223 pet->NearTeleportTo(x, y, z, player->GetOrientation());
5224 pet->Relocate(x, y, z, player->GetOrientation()); // This is needed so SaveStayPosition() will get the proper coords.
5228 pet->ClearUnitState(uint32(UNIT_STATE_ALL_STATE & ~(UNIT_STATE_POSSESSED))); // xinef: just in case
5230 pet->SetDisplayId(pet->GetNativeDisplayId());
5231
5232 // xinef: restore movement
5233 if (auto ci = pet->GetCharmInfo())
5234 {
5235 ci->SetIsAtStay(false);
5236 ci->SetIsFollowing(false);
5237 }
5238
5240}
#define PET_FOLLOW_DIST
Definition PetDefines.h:205
@ SUMMON_PET
Definition PetDefines.h:31
@ UNIT_DYNFLAG_NONE
Definition SharedDefines.h:3370
@ UNIT_STATE_POSSESSED
Definition UnitDefines.h:186
@ UNIT_STATE_ALL_STATE
Definition UnitDefines.h:222
float GetFollowAngle() const override
Definition TemporarySummon.h:83
void setDeathState(DeathState s, bool despawn=false) override
A creature can be in 4 different states: Alive, JustDied, Corpse, and JustRespawned....
Definition Pet.cpp:626
void SetDisplayId(uint32 modelId, float displayScale=1.f) override
Definition Pet.cpp:2424
Pet * SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, Milliseconds duration=0s, uint32 healthPct=0)
Definition Player.cpp:9017
void ReplaceAllDynamicFlags(uint32 flag) override
Definition Unit.h:724
void SetHealth(uint32 val)
Definition Unit.cpp:15579
uint32 GetNativeDisplayId() const
Definition Unit.h:1892
void RemoveUnitFlag(UnitFlags flags)
UnitFlags available in UnitDefines.h.
Definition Unit.h:704
bool GetClosePoint(float &x, float &y, float &z, float size, float distance2d=0, float angle=0, WorldObject const *forWho=nullptr, bool force=false) const
Definition Object.cpp:2692

References Alive, Unit::ClearUnitState(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, Unit::GetCharmInfo(), WorldObject::GetClosePoint(), Unit::GetCombatReach(), Minion::GetFollowAngle(), Unit::GetNativeDisplayId(), Position::GetOrientation(), Player::GetPet(), Unit::IsAlive(), m_caster, Unit::NearTeleportTo(), PET_FOLLOW_DIST, PET_SAVE_AS_CURRENT, Position::Relocate(), Unit::RemoveUnitFlag(), Unit::ReplaceAllDynamicFlags(), Pet::SavePetToDB(), Pet::setDeathState(), Pet::SetDisplayId(), Unit::SetHealth(), SPELL_EFFECT_HANDLE_HIT, SUMMON_PET, Player::SummonPet(), Object::ToPlayer(), UNIT_DYNFLAG_NONE, UNIT_FLAG_SKINNABLE, UNIT_STATE_ALL_STATE, and UNIT_STATE_POSSESSED.

◆ EffectSanctuary()

void Spell::EffectSanctuary ( SpellEffIndex  effIndex)
4016{
4018 return;
4019
4020 if (!unitTarget)
4021 return;
4022
4024 {
4026 // Xinef: replaced with CombatStop(false)
4029
4030 // Night Elf: Shadowmeld only resets threat temporarily
4031 if (m_spellInfo->Id != 59646)
4033
4034 if (unitTarget->IsPlayer())
4035 unitTarget->ToPlayer()->SendAttackSwingCancelAttack(); // melee and ranged forced attack cancel
4036 }
4037 else
4038 {
4039 unitTarget->getHostileRefMgr().UpdateVisibility(m_spellInfo->Id == 59646); // Night Elf: Shadowmeld
4040 unitTarget->CombatStop(true);
4041 }
4042
4043 UnitList targets;
4044 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(unitTarget, unitTarget, unitTarget->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4047 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4048 {
4049 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4050 continue;
4051
4053 {
4054 if ((*iter)->GetCurrentSpell(i) && (*iter)->GetCurrentSpell(i)->m_targets.GetUnitTargetGUID() == unitTarget->GetGUID())
4055 {
4056 SpellInfo const* si = (*iter)->GetCurrentSpell(i)->GetSpellInfo();
4057 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->IsCreature())
4058 {
4059 Creature* c = (*iter)->ToCreature();
4060 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4061 continue;
4062 }
4063 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4064 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4065 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4066 {
4067 // at least one effect truly targets an unit, interrupt the spell
4068 interrupt = true;
4069 break;
4070 }
4071 if (interrupt)
4072 (*iter)->InterruptSpell(CurrentSpellTypes(i), false);
4073 }
4074 }
4075 }
4076
4077 // Xinef: Set last sanctuary time
4079}
#define CURRENT_MAX_SPELL
Definition Unit.h:545
void UpdateVisibility(bool checkThreat)
Definition HostileRefMgr.cpp:236
void addThreatPercent(int32 percent)
Definition HostileRefMgr.cpp:85
virtual bool IsEncounterInProgress() const
Definition InstanceScript.cpp:137
void SendAttackSwingCancelAttack()
Definition PlayerMisc.cpp:140
void CombatStop(bool includingCast=false)
Definition Unit.cpp:10531
void RemoveAllAttackers()
Remove all units in m_attackers list and send them AttackStop()
Definition Unit.cpp:10579
bool AttackStop()
Force the unit to stop attacking. This will clear UNIT_STATE_MELEE_ATTACKING, Interrupt current spell...
Definition Unit.cpp:10498

References HostileRefMgr::addThreatPercent(), Unit::AttackStop(), Unit::CombatStop(), CREATURE_ELITE_WORLDBOSS, CURRENT_FIRST_NON_MELEE_SPELL, CURRENT_MAX_SPELL, effectHandleMode, SpellInfo::Effects, Creature::GetCreatureTemplate(), GameTime::GetGameTimeMS(), Object::GetGUID(), Unit::getHostileRefMgr(), WorldObject::GetInstanceScript(), WorldObject::GetVisibilityRange(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::InterruptSpell(), Creature::IsDungeonBoss(), InstanceScript::IsEncounterInProgress(), Unit::IsPet(), Object::IsPlayer(), Creature::isWorldBoss(), Unit::m_lastSanctuaryTime, m_spellInfo, MAX_SPELL_EFFECTS, CreatureTemplate::rank, Unit::RemoveAllAttackers(), Player::SendAttackSwingCancelAttack(), SPELL_ATTR6_IGNORE_PHASE_SHIFT, SPELL_EFFECT_HANDLE_HIT_TARGET, TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST, Object::ToCreature(), Object::ToPlayer(), UNIT_STATE_CASTING, unitTarget, HostileRefMgr::UpdateVisibility(), and Cell::VisitObjects().

◆ EffectSchoolDMG()

void Spell::EffectSchoolDMG ( SpellEffIndex  effIndex)
Todo:
: should this be put on taken but not done?
324{
326 return;
327
328 if (unitTarget && unitTarget->IsAlive())
329 {
330 bool apply_direct_bonus = true;
332 {
334 {
335 // Meteor like spells (divided damage to targets)
337 {
338 uint32 count = 0;
339 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
340 if (ihit->effectMask & (1 << effIndex))
341 ++count;
342
343 damage /= count; // divide to all targets
344 }
345 break;
346 }
348 {
349 // Shield Slam
350 if (m_spellInfo->SpellFamilyFlags[1] & 0x200 && m_spellInfo->GetCategory() == 1209)
351 {
352 uint8 level = m_caster->GetLevel();
353 // xinef: shield block should increase the limit
354 float limit = m_caster->HasAura(2565) ? 2.0f : 1.0f;
355 uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 24.5f * limit), uint32(float(level) * 34.5f * limit));
356
357 damage += int32(m_caster->ApplyEffectModifiers(m_spellInfo, effIndex, float(block_value)));
358 }
359 // Victory Rush
360 else if (m_spellInfo->SpellFamilyFlags[1] & 0x100)
362 // Shockwave
363 else if (m_spellInfo->Id == 46968)
364 {
366 if (pct > 0)
368 break;
369 }
370 break;
371 }
373 {
374 // Incinerate Rank 1 & 2
375 if ((m_spellInfo->SpellFamilyFlags[1] & 0x000040) && m_spellInfo->SpellIconID == 2128)
376 {
377 // Incinerate does more dmg (dmg*0.25) if the target have Immolate debuff.
378 // Check aura state for speed but aura state set not only for Immolate spell
380 {
382 damage += damage / 4;
383 }
384 }
385 // Conflagrate - consumes Immolate or Shadowflame
387 {
388 AuraEffect const* aura = nullptr; // found req. aura for damage calculation
389
391 for (Unit::AuraEffectList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i)
392 {
393 // for caster applied auras only
394 if ((*i)->GetSpellInfo()->SpellFamilyName != SPELLFAMILY_WARLOCK ||
395 (*i)->GetCasterGUID() != m_caster->GetGUID())
396 continue;
397
398 // Immolate
399 if ((*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x4)
400 {
401 aura = *i; // it selected always if exist
402 break;
403 }
404
405 // Shadowflame
406 if ((*i)->GetSpellInfo()->SpellFamilyFlags[2] & 0x00000002)
407 aura = *i; // remember but wait possible Immolate as primary priority
408 }
409
410 // found Immolate or Shadowflame
411 if (aura)
412 {
413 uint32 pdamage = uint32(std::max(aura->GetAmount(), 0));
414 pdamage = unitTarget->SpellDamageBonusTaken(m_caster, aura->GetSpellInfo(), pdamage, DOT, aura->GetBase()->GetStackAmount());
415 uint32 pct_dir = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, (effIndex + 1));
416 uint8 baseTotalTicks = uint8(m_caster->CalcSpellDuration(aura->GetSpellInfo()) / aura->GetSpellInfo()->Effects[EFFECT_0].Amplitude);
417
418 damage += int32(CalculatePct(pdamage * baseTotalTicks, pct_dir));
419
420 uint32 pct_dot = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, (effIndex + 2)) / 3;
421 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(int32(CalculatePct(pdamage * baseTotalTicks, pct_dot)));
422
423 apply_direct_bonus = false;
424 // Glyph of Conflagrate
425 if (!m_caster->HasAura(56235))
427
428 break;
429 }
430 }
431 // Shadow Bite
432 else if (m_spellInfo->SpellFamilyFlags[1] & 0x400000)
433 {
434 if (m_caster->IsCreature() && m_caster->IsPet())
435 {
436 if (Player* owner = m_caster->GetOwner()->ToPlayer())
437 {
438 if (AuraEffect* aurEff = owner->GetAuraEffect(SPELL_AURA_ADD_FLAT_MODIFIER, SPELLFAMILY_WARLOCK, 214, 0))
439 {
440 int32 bp0 = aurEff->GetId() == 54037 ? 4 : 8;
441 m_caster->CastCustomSpell(m_caster, 54425, &bp0, nullptr, nullptr, true);
442 }
443 }
444 }
445 }
446 break;
447 }
449 {
450 // Improved Mind Blast (Mind Blast in shadow form bonus)
451 if (m_caster->GetShapeshiftForm() == FORM_SHADOW && (m_spellInfo->SpellFamilyFlags[0] & 0x00002000))
452 {
454 for (Unit::AuraEffectList::const_iterator i = ImprMindBlast.begin(); i != ImprMindBlast.end(); ++i)
455 {
456 if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_PRIEST &&
457 ((*i)->GetSpellInfo()->SpellIconID == 95))
458 {
459 int chance = (*i)->GetSpellInfo()->Effects[EFFECT_1].CalcValue(m_caster);
460 if (roll_chance_i(chance))
461 // Mind Trauma
462 m_caster->CastSpell(unitTarget, 48301, true, 0);
463 break;
464 }
465 }
466 }
467 break;
468 }
470 {
471 // Ferocious Bite
472 if (m_caster->IsPlayer() && (m_spellInfo->SpellFamilyFlags[0] & 0x000800000) && m_spellInfo->SpellVisual[0] == 6587)
473 {
474 // converts each extra point of energy into ($f1+$AP/410) additional damage
476 float multiple = ap / 410 + m_spellInfo->Effects[effIndex].DamageMultiplier;
477 int32 energy = -(m_caster->ModifyPower(POWER_ENERGY, -30));
478 damage += int32(energy * multiple);
480 }
481 // Wrath
482 else if (m_spellInfo->SpellFamilyFlags[0] & 0x00000001)
483 {
484 // Improved Insect Swarm
485 if (AuraEffect const* aurEff = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 1771, 0))
487 AddPct(damage, aurEff->GetAmount());
488 }
489 break;
490 }
492 {
493 // Envenom
494 if (m_spellInfo->SpellFamilyFlags[1] & 0x00000008)
495 {
496 if (Player* player = m_caster->ToPlayer())
497 {
498 // consume from stack dozes not more that have combo-points
499 if (uint32 combo = player->GetComboPoints())
500 {
501 // Lookup for Deadly poison (only attacker applied)
503 {
504 // count consumed deadly poison doses at target
505 bool needConsume = true;
506 uint32 spellId = aurEff->GetId();
507
508 uint32 doses = aurEff->GetBase()->GetStackAmount();
509 if (doses > combo)
510 doses = combo;
511
512 // Master Poisoner
513 Unit::AuraEffectList const& auraList = player->GetAuraEffectsByType(SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK);
514 for (Unit::AuraEffectList::const_iterator iter = auraList.begin(); iter != auraList.end(); ++iter)
515 {
516 if ((*iter)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_ROGUE && (*iter)->GetSpellInfo()->SpellIconID == 1960)
517 {
518 uint32 chance = (*iter)->GetSpellInfo()->Effects[EFFECT_2].CalcValue(m_caster);
519
520 if (chance && roll_chance_i(chance))
521 needConsume = false;
522
523 break;
524 }
525 }
526
527 if (needConsume)
528 for (uint32 i = 0; i < doses; ++i)
530
531 damage *= doses;
532 damage += int32(player->GetTotalAttackPowerValue(BASE_ATTACK) * 0.09f * combo);
533 }
534
535 // Eviscerate and Envenom Bonus Damage (item set effect)
536 if (m_caster->HasAura(37169))
537 damage += combo * 40;
538 }
539 }
540 }
541 // Eviscerate
542 else if (m_spellInfo->SpellFamilyFlags[0] & 0x00020000)
543 {
544 if (m_caster->IsPlayer())
545 {
546 if (uint32 combo = m_caster->ToPlayer()->GetComboPoints())
547 {
549 damage += int32(ap * combo * 0.07f);
550
551 // Eviscerate and Envenom Bonus Damage (item set effect)
552 if (m_caster->HasAura(37169))
553 damage += combo * 40;
554 }
555 }
556 }
557 break;
558 }
560 {
561 //Gore
562 if (m_spellInfo->SpellIconID == 1578)
563 {
564 if (m_caster->HasAura(57627)) // Charge 6 sec post-affect
565 damage *= 2;
566 }
567 // Steady Shot
568 else if (m_spellInfo->SpellFamilyFlags[1] & 0x1)
569 {
570 bool found = false;
571 // check dazed affect
573 for (Unit::AuraEffectList::const_iterator iter = decSpeedList.begin(); iter != decSpeedList.end(); ++iter)
574 {
575 if ((*iter)->GetSpellInfo()->SpellIconID == 15 && (*iter)->GetSpellInfo()->Dispel == 0)
576 {
577 found = true;
578 break;
579 }
580 }
581
583 if (found)
584 damage += m_spellInfo->Effects[EFFECT_1].CalcValue();
585
586 if (Player* caster = m_caster->ToPlayer())
587 {
588 // Add Ammo and Weapon damage plus RAP * 0.1
589 float dmg_min = 0.f;
590 float dmg_max = 0.f;
591 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
592 {
593 dmg_min += caster->GetWeaponDamageRange(RANGED_ATTACK, MINDAMAGE, i);
594 dmg_max += caster->GetWeaponDamageRange(RANGED_ATTACK, MAXDAMAGE, i);
595 }
596
597 if (dmg_max == 0.0f && dmg_min > dmg_max)
598 {
599 damage += int32(dmg_min);
600 }
601 else
602 {
603 damage += irand(int32(dmg_min), int32(dmg_max));
604 }
605 damage += int32(caster->GetAmmoDPS() * caster->GetAttackTime(RANGED_ATTACK) * 0.001f);
606 }
607 }
608 break;
609 }
611 {
612 // Hammer of the Righteous
613 if (m_spellInfo->SpellFamilyFlags[1] & 0x00040000)
614 {
615 // Add main hand dps * effect[2] amount
616 if (Player* player = m_caster->ToPlayer())
617 {
618 float minTotal = 0.f;
619 float maxTotal = 0.f;
620 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
621 {
622 float tmpMin, tmpMax;
623 player->CalculateMinMaxDamage(BASE_ATTACK, false, false, tmpMin, tmpMax, i);
624 minTotal += tmpMin;
625 maxTotal += tmpMax;
626 }
627
628 float average = (minTotal + maxTotal) / 2;
631 }
632 break;
633 }
634 // Shield of Righteousness
635 if (m_spellInfo->SpellFamilyFlags[EFFECT_1] & 0x100000)
636 {
637 uint8 level = m_caster->GetLevel();
638 uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 29.5f), uint32(float(level) * 34.5f));
639 if (m_caster->GetAuraEffect(64882, EFFECT_0))
640 block_value += 225;
641 damage += CalculatePct(block_value, m_spellInfo->Effects[EFFECT_1].CalcValue());
642 break;
643 }
644 break;
645 }
646 }
647
648 if (m_originalCaster /*&& damage > 0 Xinef: this can be increased from 0*/ && apply_direct_bonus)
649 {
650 // Xinef: protection
651 if (damage < 0)
652 damage = 0;
653
656 }
657
658 m_damage += damage;
659 }
660}
#define MAX_ITEM_PROTO_DAMAGES
Definition ItemTemplate.h:613
@ EFFECT_2
Definition SharedDefines.h:33
@ POWER_ENERGY
Definition SharedDefines.h:283
@ SPELLFAMILY_PRIEST
Definition SharedDefines.h:3800
@ AURA_STATE_CONFLAGRATE
Definition SharedDefines.h:1317
@ SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK
Definition SpellAuraDefines.h:309
@ SPELL_AURA_PERIODIC_DAMAGE
Definition SpellAuraDefines.h:66
@ SPELL_AURA_ADD_FLAT_MODIFIER
Definition SpellAuraDefines.h:170
@ SPELL_AURA_MOD_DECREASE_SPEED
Definition SpellAuraDefines.h:96
@ SPELL_ATTR0_CU_SHARE_DAMAGE
Definition SpellInfo.h:180
@ FORM_SHADOW
Definition UnitDefines.h:95
@ MINDAMAGE
Definition Unit.h:136
@ MAXDAMAGE
Definition Unit.h:137
uint8 GetStackAmount() const
Definition SpellAuras.h:148
float GetTotalAttackPowerValue(WeaponAttackType attType, Unit *pVictim=nullptr) const
Definition Unit.cpp:15529
float ApplyEffectModifiers(SpellInfo const *spellProto, uint8 effect_index, float value) const
Definition Unit.cpp:14930
virtual uint32 GetShieldBlockValue() const =0
void RemoveAuraFromStack(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:4990
uint32 GetAttackTime(WeaponAttackType att) const
Definition Unit.h:861
AuraEffect * GetDummyAuraEffect(SpellFamilyNames name, uint32 iconId, uint8 effIndex) const
Definition Unit.h:1362

References AddPct(), Unit::ApplyEffectModifiers(), ApplyPct(), AURA_STATE_CONFLAGRATE, BASE_ATTACK, Unit::CalcSpellDuration(), CalculatePct(), Unit::CalculateSpellDamage(), Unit::CastCustomSpell(), Unit::CastSpell(), damage, DOT, EFFECT_0, EFFECT_1, EFFECT_2, SpellValue::EffectBasePoints, effectHandleMode, SpellInfo::Effects, FORM_SHADOW, AuraEffect::GetAmount(), Unit::GetAttackTime(), Unit::GetAuraEffect(), Unit::GetAuraEffectsByType(), AuraEffect::GetBase(), SpellInfo::GetCategory(), Unit::GetComboPoints(), Unit::GetDummyAuraEffect(), Object::GetGUID(), AuraEffect::GetId(), Unit::GetLevel(), Unit::GetOwner(), Unit::GetShapeshiftForm(), Unit::GetShieldBlockValue(), AuraEffect::GetSpellInfo(), Aura::GetStackAmount(), Unit::GetTotalAttackPowerValue(), SpellInfo::HasAttribute(), Unit::HasAura(), Unit::HasAuraState(), SpellInfo::Id, IN_MILLISECONDS, irand(), Unit::IsAlive(), Object::IsCreature(), Unit::IsPet(), Object::IsPlayer(), m_caster, m_damage, m_originalCaster, m_spellInfo, m_spellValue, m_UniqueTargetInfo, MAX_ITEM_PROTO_DAMAGES, MAXDAMAGE, MINDAMAGE, Unit::ModifyPower(), POWER_ENERGY, RANGED_ATTACK, Unit::RemoveAuraFromStack(), Unit::RemoveAurasDueToSpell(), roll_chance_i(), SPELL_ATTR0_CU_SHARE_DAMAGE, SPELL_AURA_ADD_FLAT_MODIFIER, SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK, SPELL_AURA_MOD_DECREASE_SPEED, SPELL_AURA_PERIODIC_DAMAGE, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), SPELLFAMILY_DRUID, SPELLFAMILY_GENERIC, SPELLFAMILY_HUNTER, SPELLFAMILY_PALADIN, SPELLFAMILY_PRIEST, SPELLFAMILY_ROGUE, SPELLFAMILY_WARLOCK, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellIconID, SpellInfo::SpellVisual, SpellInfo::TargetAuraState, Object::ToPlayer(), and unitTarget.

◆ EffectScriptEffect()

void Spell::EffectScriptEffect ( SpellEffIndex  effIndex)
Todo:
: we must implement hunter pet summon at login there (spell 6962)
3780{
3782 return;
3783
3785
3787 {
3789 {
3790 switch (m_spellInfo->Id)
3791 {
3792 // Shadow Flame (All script effects, not just end ones to prevent player from dodging the last triggered spell)
3793 case 22539:
3794 case 22972:
3795 case 22975:
3796 case 22976:
3797 case 22977:
3798 case 22978:
3799 case 22979:
3800 case 22980:
3801 case 22981:
3802 case 22982:
3803 case 22983:
3804 case 22984:
3805 case 22985:
3806 {
3807 if (!unitTarget || !unitTarget->IsAlive())
3808 return;
3809
3810 // Onyxia Scale Cloak
3811 if (unitTarget->HasAura(22683))
3812 return;
3813
3814 // Shadow Flame
3815 m_caster->CastSpell(unitTarget, 22682, true);
3816 return;
3817 }
3818 // Plant Warmaul Ogre Banner
3819 case 32307:
3820 if (Player* caster = m_caster->ToPlayer())
3821 {
3822 caster->RewardPlayerAndGroupAtEvent(18388, unitTarget);
3823 if (Creature* target = unitTarget->ToCreature())
3824 {
3825 target->setDeathState(DeathState::Corpse);
3826 target->RemoveCorpse();
3827 }
3828 }
3829 break;
3830 // SOTA defender teleport
3831 case 54640:
3832 {
3833 if (Player* player = unitTarget->ToPlayer())
3834 if (player->GetBattleground() && player->GetBattleground()->GetBgTypeID(true) == BATTLEGROUND_SA)
3835 {
3836 if (GameObject* dportal = player->FindNearestGameObject(192819, 10.0f))
3837 {
3838 BattlegroundSA* bg = ((BattlegroundSA*)player->GetBattleground());
3839 bg->DefendersPortalTeleport(dportal, player);
3840 }
3841 }
3842 return;
3843 }
3844 /*// Mug Transformation
3845 case 41931:
3846 {
3847 if (!m_caster->IsPlayer())
3848 return;
3849
3850 uint8 bag = 19;
3851 uint8 slot = 0;
3852 Item* item = nullptr;
3853
3854 while (bag) // 256 = 0 due to var type
3855 {
3856 item = m_caster->ToPlayer()->GetItemByPos(bag, slot);
3857 if (item && item->GetEntry() == 38587)
3858 break;
3859
3860 ++slot;
3861 if (slot == 39)
3862 {
3863 slot = 0;
3864 ++bag;
3865 }
3866 }
3867 if (bag)
3868 {
3869 if (m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount() == 1) m_caster->ToPlayer()->RemoveItem(bag, slot, true);
3870 else m_caster->ToPlayer()->GetItemByPos(bag, slot)->SetCount(m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount()-1);
3871 // Spell 42518 (Braufest - Gratisprobe des Braufest herstellen)
3872 m_caster->CastSpell(m_caster, 42518, true);
3873 return;
3874 }
3875 break;
3876 }*/
3877 // Roll Dice - Decahedral Dwarven Dice
3878 case 47770:
3879 {
3880 char buf[128];
3881 const char* gender = "his";
3882 if (m_caster->getGender() > 0)
3883 gender = "her";
3884 snprintf(buf, sizeof(buf), "%s rubs %s [Decahedral Dwarven Dice] between %s hands and rolls. One %u and one %u.", m_caster->GetName().c_str(), gender, gender, urand(1, 10), urand(1, 10));
3885 m_caster->TextEmote(buf);
3886 break;
3887 }
3888 case 52173: // Coyote Spirit Despawn
3889 case 60243: // Blood Parrot Despawn
3892 return;
3893 case 57347: // Retrieving (Wintergrasp RP-GG pickup spell)
3894 {
3896 return;
3897
3899
3900 return;
3901 }
3902 case 57349: // Drop RP-GG (Wintergrasp RP-GG at death drop spell)
3903 {
3904 if (!m_caster->IsPlayer())
3905 return;
3906
3907 // Delete item from inventory at death
3909
3910 return;
3911 }
3912 case 58418: // Portal to Orgrimmar
3913 case 58420: // Portal to Stormwind
3914 {
3915 if (!unitTarget || !unitTarget->IsPlayer() || effIndex != 0)
3916 return;
3917
3918 uint32 spellID = m_spellInfo->Effects[EFFECT_0].CalcValue();
3919 uint32 questID = m_spellInfo->Effects[EFFECT_1].CalcValue();
3920
3922 unitTarget->CastSpell(unitTarget, spellID, true);
3923
3924 return;
3925 }
3926 // Stoneclaw Totem
3927 case 55328: // Rank 1
3928 case 55329: // Rank 2
3929 case 55330: // Rank 3
3930 case 55332: // Rank 4
3931 case 55333: // Rank 5
3932 case 55335: // Rank 6
3933 case 55278: // Rank 7
3934 case 58589: // Rank 8
3935 case 58590: // Rank 9
3936 case 58591: // Rank 10
3937 {
3938 int32 basepoints0 = damage;
3939 // Cast Absorb on totems
3940 for (uint8 slot = SUMMON_SLOT_TOTEM_FIRE; slot < MAX_TOTEM_SLOT; ++slot)
3941 {
3942 if (!unitTarget->m_SummonSlot[slot])
3943 continue;
3944
3946 if (totem && totem->IsTotem())
3947 {
3948 m_caster->CastCustomSpell(totem, 55277, &basepoints0, nullptr, nullptr, true);
3949 }
3950 }
3951 // Glyph of Stoneclaw Totem
3952 if (AuraEffect* aur = unitTarget->GetAuraEffect(63298, 0))
3953 {
3954 basepoints0 *= aur->GetAmount();
3955 m_caster->CastCustomSpell(unitTarget, 55277, &basepoints0, nullptr, nullptr, true);
3956 }
3957 break;
3958 }
3959 case 61263: // for item Intravenous Healing Potion (44698)
3960 {
3961 if (!m_caster || !unitTarget)
3962 return;
3963
3964 m_caster->CastSpell(m_caster, 61267, true);
3965 m_caster->CastSpell(m_caster, 61268, true);
3966 return;
3967 }
3968 }
3969 break;
3970 }
3971 case SPELLFAMILY_ROGUE:
3972 {
3973 switch (m_spellInfo->Id)
3974 {
3975 // Master of Subtlety
3976 case 31666:
3977 {
3978 if (!unitTarget)
3979 return;
3980
3981 Aura* mos = unitTarget->GetAura(31665);
3982 if (mos)
3983 {
3984 mos->SetMaxDuration(6000);
3985 mos->SetDuration(6000, true);
3986 }
3987
3988 break;
3989 }
3990 // Overkill
3991 case 58428:
3992 {
3993 if (!unitTarget)
3994 return;
3995
3996 Aura* overkill = unitTarget->GetAura(58427);
3997 if (overkill)
3998 {
3999 overkill->SetMaxDuration(20000);
4000 overkill->SetDuration(20000, true);
4001 }
4002
4003 break;
4004 }
4005 }
4006 break;
4007 }
4008 }
4009
4010 // normal DB scripted effect
4011 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectScriptEffect({})", m_spellInfo->Id, effIndex);
4013}
@ QUEST_STATUS_COMPLETE
Definition QuestDef.h:101
@ BATTLEGROUND_SA
Definition SharedDefines.h:3755
Class for manage Strand of Ancient battleground.
Definition BattlegroundSA.h:428
void DefendersPortalTeleport(GameObject *portal, Player *plr)
Definition BattlegroundSA.cpp:587
void DespawnOrUnsummon(Milliseconds msTimeToDespawn, Seconds forcedRespawnTimer)
Definition Creature.cpp:2180
virtual void UnSummon(uint32 msTime=0)
Definition TemporarySummon.cpp:287
uint8 getGender() const
Definition Unit.h:800
bool IsSummon() const
Definition Unit.h:746
virtual void TextEmote(std::string_view text, WorldObject const *target=nullptr, bool isBossEmote=false)
Definition Unit.cpp:21009
GameObject * FindNearestGameObject(uint32 entry, float range, bool onlySpawned=false) const
Definition Object.cpp:2434
std::string const & GetName() const
Definition Object.h:525

References BATTLEGROUND_SA, Unit::CastCustomSpell(), Unit::CastSpell(), Corpse, damage, BattlegroundSA::DefendersPortalTeleport(), Creature::DespawnOrUnsummon(), Player::DestroyItemCount(), EFFECT_0, EFFECT_1, effectHandleMode, SpellInfo::Effects, WorldObject::FindNearestGameObject(), Unit::GetAura(), Unit::GetAuraEffect(), Map::GetCreature(), Unit::getGender(), WorldObject::GetMap(), WorldObject::GetName(), Player::GetQuestStatus(), Unit::HasAura(), SpellInfo::Id, Unit::IsAlive(), Object::IsCreature(), Object::IsPlayer(), Unit::IsSummon(), Unit::IsTotem(), LOG_DEBUG, m_caster, m_spellInfo, Unit::m_SummonSlot, MAX_TOTEM_SLOT, QUEST_STATUS_COMPLETE, Map::ScriptsStart(), Aura::SetDuration(), Aura::SetMaxDuration(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SPELLFAMILY_ROGUE, SpellInfo::SpellFamilyName, sSpellScripts, SUMMON_SLOT_TOTEM_FIRE, Unit::TextEmote(), Object::ToCreature(), Object::ToPlayer(), Unit::ToTempSummon(), unitTarget, TempSummon::UnSummon(), and urand().

◆ EffectSelfResurrect()

void Spell::EffectSelfResurrect ( SpellEffIndex  effIndex)
4842{
4844 return;
4845
4846 if (!m_caster || m_caster->IsAlive())
4847 return;
4848 if (!m_caster->IsPlayer())
4849 return;
4850 if (!m_caster->IsInWorld())
4851 return;
4852
4853 uint32 health = 0;
4854 uint32 mana = 0;
4855
4856 // flat case
4857 if (damage < 0)
4858 {
4859 health = uint32(-damage);
4860 mana = m_spellInfo->Effects[effIndex].MiscValue;
4861 }
4862 // percent case
4863 else
4864 {
4868 }
4869
4870 Player* player = m_caster->ToPlayer();
4871 player->ResurrectPlayer(0.0f);
4872
4873 player->SetHealth(health);
4874 player->SetPower(POWER_MANA, mana);
4875 player->SetPower(POWER_RAGE, 0);
4876 player->SetPower(POWER_ENERGY, player->GetMaxPower(POWER_ENERGY));
4877
4878 player->SpawnCorpseBones();
4879}
@ POWER_RAGE
Definition SharedDefines.h:281
void SpawnCorpseBones(bool triggerSave=true)
Definition Player.cpp:4723
void ResurrectPlayer(float restore_percent, bool applySickness=false)
Definition Player.cpp:4504
void SetPower(Powers power, uint32 val, bool withPowerUpdate=true, bool fromRegenerate=false)
Definition Unit.cpp:15667

References CalculatePct(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, SpellInfo::Effects, Unit::GetMaxPower(), Unit::IsAlive(), Object::IsInWorld(), Object::IsPlayer(), m_caster, m_spellInfo, POWER_ENERGY, POWER_MANA, POWER_RAGE, Player::ResurrectPlayer(), Unit::SetHealth(), Unit::SetPower(), Player::SpawnCorpseBones(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectSendEvent()

void Spell::EffectSendEvent ( SpellEffIndex  effIndex)
Todo:
: there should be a possibility to pass dest target to event script
1390{
1391 // we do not handle a flag dropping or clicking on flag in battleground by sendevent system
1394 return;
1395
1396 WorldObject* target = nullptr;
1397
1398 // call events for object target if present
1400 {
1401 if (unitTarget)
1402 target = unitTarget;
1403 else if (gameObjTarget)
1404 target = gameObjTarget;
1405 }
1406 else // if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
1407 {
1408 // let's prevent executing effect handler twice in case when spell effect is capable of targeting an object
1409 // this check was requested by scripters, but it has some downsides:
1410 // now it's impossible to script (using sEventScripts) a cast which misses all targets
1411 // or to have an ability to script the moment spell hits dest (in a case when there are object targets present)
1412 if (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_GAMEOBJECT_MASK))
1413 return;
1414 // some spells have no target entries in dbc and they use focus target
1415 if (focusObject)
1416 target = focusObject;
1418 }
1419
1420 LOG_DEBUG("spells.aura", "Spell ScriptStart {} for spellid {} in EffectSendEvent ", m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
1421
1422 if (ZoneScript* zoneScript = m_caster->GetZoneScript())
1423 zoneScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
1424 else if (InstanceScript* instanceScript = m_caster->GetInstanceScript()) // needed in case Player is the caster
1425 instanceScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
1426
1427 m_caster->GetMap()->ScriptsStart(sEventScripts, m_spellInfo->Effects[effIndex].MiscValue, m_caster, target);
1428}
ScriptMapMap sEventScripts
Definition ObjectMgr.cpp:60
@ TARGET_FLAG_UNIT_MASK
Definition SpellInfo.h:69
@ TARGET_FLAG_GAMEOBJECT_MASK
Definition SpellInfo.h:71
Definition Object.h:472
ZoneScript * GetZoneScript() const
Definition Object.h:627
Definition ZoneScript.h:26

References effectHandleMode, SpellInfo::Effects, focusObject, gameObjTarget, WorldObject::GetInstanceScript(), WorldObject::GetMap(), WorldObject::GetZoneScript(), SpellInfo::Id, LOG_DEBUG, m_caster, m_spellInfo, Map::ScriptsStart(), sEventScripts, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_UNIT_MASK, and unitTarget.

◆ EffectSendTaxi()

void Spell::EffectSendTaxi ( SpellEffIndex  effIndex)
5101{
5103 return;
5104
5105 if (!unitTarget)
5106 return;
5107
5108 if (Player* player = unitTarget->ToPlayer())
5109 {
5110 player->ActivateTaxiPathTo(m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
5111 }
5112}

References effectHandleMode, SpellInfo::Effects, SpellInfo::Id, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSkill()

void Spell::EffectSkill ( SpellEffIndex  effIndex)
5534{
5536 return;
5537
5538 LOG_DEBUG("spells.aura", "WORLD: SkillEFFECT");
5539}

References effectHandleMode, LOG_DEBUG, and SPELL_EFFECT_HANDLE_HIT.

◆ EffectSkinning()

void Spell::EffectSkinning ( SpellEffIndex  effIndex)
4882{
4884 return;
4885
4886 if (!unitTarget->IsCreature())
4887 return;
4888 if (!m_caster->IsPlayer())
4889 return;
4890
4891 Creature* creature = unitTarget->ToCreature();
4892 int32 targetLevel = creature->GetLevel();
4893
4894 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
4895
4899
4900 int32 reqValue = targetLevel < 10 ? 0 : targetLevel < 20 ? (targetLevel - 10) * 10 : targetLevel * 5;
4901
4902 int32 skillValue = m_caster->ToPlayer()->GetPureSkillValue(skill);
4903
4904 // Double chances for elites
4905 m_caster->ToPlayer()->UpdateGatherSkill(skill, skillValue, reqValue, creature->isElite() ? 2 : 1);
4906}
@ UNIT_DYNFLAG_LOOTABLE
Definition SharedDefines.h:3371
bool isElite() const
Definition Creature.h:112
virtual void SetDynamicFlag(uint32 flag)
Definition Object.h:124

References effectHandleMode, Creature::GetCreatureTemplate(), Object::GetGUID(), Unit::GetLevel(), Player::GetPureSkillValue(), CreatureTemplate::GetRequiredLootSkill(), Object::IsCreature(), Creature::isElite(), Object::IsPlayer(), LOOT_SKINNING, m_caster, Unit::RemoveUnitFlag(), Player::SendLoot(), Object::SetDynamicFlag(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), UNIT_DYNFLAG_LOOTABLE, UNIT_FLAG_SKINNABLE, unitTarget, and Player::UpdateGatherSkill().

◆ EffectSkinPlayerCorpse()

void Spell::EffectSkinPlayerCorpse ( SpellEffIndex  effIndex)
5565{
5567 return;
5568
5569 LOG_DEBUG("spells.aura", "Effect: SkinPlayerCorpse");
5570 if ((!m_caster->IsPlayer()) || (!unitTarget->IsPlayer()) || (unitTarget->IsAlive()))
5571 return;
5572
5574
5575 // We have a corpse object as the target.
5576 // This target was deleted in RemovedInsignia() -> ConvertCorpseToBones().
5578}
void RemovedInsignia(Player *looterPlr)
Definition Player.cpp:7809
void RemoveObjectTarget()
Definition Spell.cpp:321

References effectHandleMode, Unit::IsAlive(), Object::IsPlayer(), LOG_DEBUG, m_caster, m_targets, Player::RemovedInsignia(), SpellCastTargets::RemoveObjectTarget(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSpecCount()

void Spell::EffectSpecCount ( SpellEffIndex  effIndex)
6124{
6126 return;
6127
6128 if (!unitTarget)
6129 return;
6130
6131 if (Player* player = unitTarget->ToPlayer())
6132 {
6133 player->UpdateSpecCount(damage);
6134 }
6135}

References damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSpiritHeal()

void Spell::EffectSpiritHeal ( SpellEffIndex  effIndex)
5546{
5548 return;
5549
5550 /*
5551 if (!unitTarget->IsPlayer())
5552 return;
5553 if (!unitTarget->IsInWorld())
5554 return;
5555
5556 //m_spellInfo->Effects[i].BasePoints; == 99 (percent?)
5557 //unitTarget->ToPlayer()->setResurrect(m_caster->GetGUID(), unitTarget->GetPositionX(), unitTarget->GetPositionY(), unitTarget->GetPositionZ(), unitTarget->GetMaxHealth(), unitTarget->GetMaxPower(POWER_MANA));
5558 unitTarget->ToPlayer()->ResurrectPlayer(1.0f);
5559 unitTarget->ToPlayer()->SpawnCorpseBones();
5560 */
5561}

References effectHandleMode, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectStealBeneficialBuff()

void Spell::EffectStealBeneficialBuff ( SpellEffIndex  effIndex)
5581{
5583 return;
5584
5585 LOG_DEBUG("spells.aura", "Effect: StealBeneficialBuff");
5586
5587 if (!unitTarget || unitTarget == m_caster) // can't steal from self
5588 return;
5589
5590 DispelChargesList steal_list;
5591
5592 // Create dispel mask by dispel type
5593 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[effIndex].MiscValue));
5594 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5595 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5596 {
5597 Aura* aura = itr->second;
5599 if (!aurApp)
5600 continue;
5601
5602 if ((aura->GetSpellInfo()->GetDispelMask()) & dispelMask)
5603 {
5604 // Need check for passive? this
5605 if (!aurApp->IsPositive() || aura->IsPassive() || aura->GetSpellInfo()->HasAttribute(SPELL_ATTR4_CANNOT_BE_STOLEN))
5606 continue;
5607
5608 // The charges / stack amounts don't count towards the total number of auras that can be dispelled.
5609 // Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
5610 // Polymorph instead of 1 / (5 + 1) -> 16%.
5611 bool dispel_charges = aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_REMOVES_CHARGES);
5612 uint8 charges = dispel_charges ? aura->GetCharges() : aura->GetStackAmount();
5613 if (charges > 0)
5614 steal_list.push_back(std::make_pair(aura, charges));
5615 }
5616 }
5617
5618 if (steal_list.empty())
5619 return;
5620
5621 // Ok if exist some buffs for dispel try dispel it
5622 uint32 failCount = 0;
5623 DispelList success_list;
5624 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
5625 // dispel N = damage buffs (or while exist buffs for dispel)
5626 for (int32 count = 0; count < damage && !steal_list.empty();)
5627 {
5628 // Random select buff for dispel
5629 DispelChargesList::iterator itr = steal_list.begin();
5630 std::advance(itr, urand(0, steal_list.size() - 1));
5631
5632 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(m_caster));
5633 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
5634 if (!chance)
5635 {
5636 steal_list.erase(itr);
5637 continue;
5638 }
5639 else
5640 {
5641 if (roll_chance_i(chance))
5642 {
5643 success_list.push_back(std::make_pair(itr->first->GetId(), itr->first->GetCasterGUID()));
5644 --itr->second;
5645 if (itr->second <= 0)
5646 steal_list.erase(itr);
5647 }
5648 else
5649 {
5650 if (!failCount)
5651 {
5652 // Failed to dispell
5653 dataFail << m_caster->GetGUID(); // Caster GUID
5654 dataFail << unitTarget->GetGUID(); // Victim GUID
5655 dataFail << uint32(m_spellInfo->Id); // dispel spell id
5656 }
5657 ++failCount;
5658 dataFail << uint32(itr->first->GetId()); // Spell Id
5659 }
5660 ++count;
5661 }
5662 }
5663
5664 if (failCount)
5665 m_caster->SendMessageToSet(&dataFail, true);
5666
5667 if (success_list.empty())
5668 return;
5669
5670 WorldPacket dataSuccess(SMSG_SPELLSTEALLOG, 8 + 8 + 4 + 1 + 4 + damage * 5);
5671 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
5672 dataSuccess << m_caster->GetPackGUID(); // Caster GUID
5673 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
5674 dataSuccess << uint8(0); // not used
5675 dataSuccess << uint32(success_list.size()); // count
5676 for (DispelList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
5677 {
5678 dataSuccess << uint32(itr->first); // Spell Id
5679 dataSuccess << uint8(0); // 0 - steals !=0 transfers
5680 unitTarget->RemoveAurasDueToSpellBySteal(itr->first, itr->second, m_caster);
5681 }
5682 m_caster->SendMessageToSet(&dataSuccess, true);
5683}
@ SPELL_ATTR7_DISPEL_REMOVES_CHARGES
Definition SharedDefines.h:662
@ SPELL_ATTR4_CANNOT_BE_STOLEN
Definition SharedDefines.h:547
std::list< std::pair< uint32, ObjectGuid > > DispelList
Definition SpellEffects.cpp:2565
bool IsPositive() const
Definition SpellAuras.h:68
uint8 GetCharges() const
Definition SpellAuras.h:141
bool IsPassive() const
Definition SpellAuras.cpp:1082
void RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, Unit *stealer)
Definition Unit.cpp:5071
@ SMSG_SPELLSTEALLOG
Definition Opcodes.h:849

References damage, effectHandleMode, SpellInfo::Effects, Aura::GetApplicationOfTarget(), Aura::GetCharges(), SpellInfo::GetDispelMask(), Object::GetGUID(), Unit::GetOwnedAuras(), Object::GetPackGUID(), Aura::GetSpellInfo(), Aura::GetStackAmount(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsFriendlyTo(), Aura::IsPassive(), AuraApplication::IsPositive(), LOG_DEBUG, m_caster, m_spellInfo, Unit::RemoveAurasDueToSpellBySteal(), roll_chance_i(), WorldObject::SendMessageToSet(), SMSG_DISPEL_FAILED, SMSG_SPELLSTEALLOG, SPELL_ATTR4_CANNOT_BE_STOLEN, SPELL_ATTR7_DISPEL_REMOVES_CHARGES, SPELL_EFFECT_HANDLE_HIT_TARGET, unitTarget, and urand().

◆ EffectStuck()

void Spell::EffectStuck ( SpellEffIndex  effIndex)
4173{
4175 return;
4176
4177 if (!m_caster->IsPlayer())
4178 return;
4179
4180 Player* target = m_caster->ToPlayer();
4181 if (target->IsInFlight())
4182 return;
4183
4184 // xinef: if player is dead - teleport to graveyard
4185 if (!target->IsAlive())
4186 {
4187 if (target->HasPreventResurectionAura())
4188 return;
4189
4190 // xinef: player is in corpse
4191 if (!target->HasPlayerFlag(PLAYER_FLAGS_GHOST))
4192 target->BuildPlayerRepop();
4193 target->RepopAtGraveyard();
4194 return;
4195 }
4196
4197 // xinef: no hearthstone in bag or on cooldown
4198 Item* hearthStone = target->GetItemByEntry(6948);
4199 if (!hearthStone || target->HasSpellCooldown(8690))
4200 {
4201 float o = rand_norm() * 2 * M_PI;
4202 Position pos = *target;
4203 target->MovePositionToFirstCollision(pos, 5.0f, o);
4204 target->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), target->GetOrientation());
4205 return;
4206 }
4207
4208 // xinef: we have hearthstone not on cooldown, just use it
4210}
@ PLAYER_FLAGS_GHOST
Definition Player.h:473
double rand_norm()
Definition Random.cpp:85
void RepopAtGraveyard()
Definition Player.cpp:4955
void BuildPlayerRepop()
Definition Player.cpp:4455
bool HasPreventResurectionAura() const
Definition Unit.h:1724
void MovePositionToFirstCollision(Position &pos, float dist, float angle)
Definition Object.cpp:2851

References Player::BuildPlayerRepop(), Unit::CastSpell(), effectHandleMode, Player::GetItemByEntry(), Position::GetOrientation(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Player::HasPlayerFlag(), Unit::HasPreventResurectionAura(), Player::HasSpellCooldown(), Unit::IsAlive(), Unit::IsInFlight(), Object::IsPlayer(), m_caster, WorldObject::MovePositionToFirstCollision(), Unit::NearTeleportTo(), PLAYER_FLAGS_GHOST, rand_norm(), Player::RepopAtGraveyard(), SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), TRIGGERED_FULL_MASK, and TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD.

◆ EffectSummonChangeItem()

void Spell::EffectSummonChangeItem ( SpellEffIndex  effIndex)
2199{
2201 return;
2202
2203 if (!m_caster->IsPlayer())
2204 return;
2205
2206 Player* player = m_caster->ToPlayer();
2207
2208 // applied only to using item
2209 if (!m_CastItem)
2210 return;
2211
2212 // ... only to item in own inventory/bank/equip_slot
2213 if (m_CastItem->GetOwnerGUID() != player->GetGUID())
2214 return;
2215
2216 uint32 newitemid = m_spellInfo->Effects[effIndex].ItemType;
2217 if (!newitemid)
2218 return;
2219
2220 uint16 pos = m_CastItem->GetPos();
2221
2222 Item* pNewItem = Item::CreateItem(newitemid, 1, player);
2223 if (!pNewItem)
2224 return;
2225
2226 // Client-side enchantment durations update
2228
2232
2234 {
2236 player->DurabilityLoss(pNewItem, lossPercent);
2237 }
2238
2239 if (player->IsInventoryPos(pos))
2240 {
2241 ItemPosCountVec dest;
2242 InventoryResult msg = player->CanStoreItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2243 if (msg == EQUIP_ERR_OK)
2244 {
2245 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2246
2247 // prevent crash at access and unexpected charges counting with item update queue corrupt
2249 m_targets.SetItemTarget(nullptr);
2250
2251 m_CastItem = nullptr;
2253
2254 player->StoreItem(dest, pNewItem, true);
2255 player->ItemAddedQuestCheck(pNewItem->GetEntry(), 1);
2256 return;
2257 }
2258 }
2259 else if (player->IsBankPos(pos))
2260 {
2261 ItemPosCountVec dest;
2262 uint8 msg = player->CanBankItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2263 if (msg == EQUIP_ERR_OK)
2264 {
2265 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2266
2267 // prevent crash at access and unexpected charges counting with item update queue corrupt
2269 m_targets.SetItemTarget(nullptr);
2270
2271 m_CastItem = nullptr;
2273
2274 player->BankItem(dest, pNewItem, true);
2275 return;
2276 }
2277 }
2278 else if (player->IsEquipmentPos(pos))
2279 {
2280 uint16 dest;
2281
2282 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2283
2284 uint8 msg = player->CanEquipItem(m_CastItem->GetSlot(), dest, pNewItem, true);
2285
2286 if (msg == EQUIP_ERR_OK || msg == EQUIP_ERR_CANT_DO_RIGHT_NOW)
2287 {
2289
2290 // prevent crash at access and unexpected charges counting with item update queue corrupt
2292 m_targets.SetItemTarget(nullptr);
2293
2294 m_CastItem = nullptr;
2296
2297 player->EquipItem(dest, pNewItem, true);
2298 player->AutoUnequipOffhandIfNeed();
2299 return;
2300 }
2301 }
2302
2303 // fail
2304 delete pNewItem;
2305}
@ EQUIP_ERR_CANT_DO_RIGHT_NOW
Definition Item.h:86
@ ITEM_FIELD_DURABILITY
Definition UpdateFields.h:69
@ ITEM_FIELD_MAXDURABILITY
Definition UpdateFields.h:70
uint8 GetSlot() const
Definition Item.h:281
static Item * CreateItem(uint32 item, uint32 count, Player const *player=nullptr, bool clone=false, uint32 randomPropertyId=0)
Definition Item.cpp:1087
uint32 GetEnchantmentDuration(EnchantmentSlot slot) const
Definition Item.h:305
uint16 GetPos() const
Definition Item.h:285
uint32 GetEnchantmentCharges(EnchantmentSlot slot) const
Definition Item.h:306
uint8 GetBagSlot() const
Definition Item.cpp:784
void Clear()
Definition ObjectGuid.h:138
static bool IsEquipmentPos(uint16 pos)
Definition Player.h:1269
InventoryResult CanEquipItem(uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition PlayerStorage.cpp:1805
Item * BankItem(ItemPosCountVec const &dest, Item *pItem, bool update)
Definition Player.h:1338
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap=false) const
Definition Player.h:1289
void UpdateEnchantmentDurations()
Definition PlayerStorage.cpp:4734
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
Definition PlayerStorage.cpp:2574
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition PlayerStorage.cpp:3018
static bool IsInventoryPos(uint16 pos)
Definition Player.h:1267
void AutoUnequipOffhandIfNeed(bool force=false)
Definition Player.cpp:12490
Item * EquipItem(uint16 pos, Item *pItem, bool update)
Definition PlayerStorage.cpp:2721
InventoryResult CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition PlayerStorage.cpp:2032
void ItemAddedQuestCheck(uint32 entry, uint32 count)
Definition PlayerQuest.cpp:1835
static bool IsBankPos(uint16 pos)
Definition Player.h:1272

References Player::AutoUnequipOffhandIfNeed(), Player::BankItem(), Player::CanBankItem(), Player::CanEquipItem(), Player::CanStoreItem(), ObjectGuid::Clear(), Item::CreateItem(), Player::DestroyItem(), Player::DurabilityLoss(), effectHandleMode, SpellInfo::Effects, EQUIP_ERR_CANT_DO_RIGHT_NOW, EQUIP_ERR_OK, Player::EquipItem(), EQUIPMENT_SLOT_MAINHAND, Item::GetBagSlot(), Item::GetEnchantmentCharges(), Item::GetEnchantmentDuration(), Item::GetEnchantmentId(), Object::GetEntry(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), Item::GetOwnerGUID(), Item::GetPos(), Item::GetSlot(), Object::GetUInt32Value(), Player::IsBankPos(), Player::IsEquipmentPos(), Player::IsInventoryPos(), Object::IsPlayer(), ITEM_FIELD_DURABILITY, ITEM_FIELD_MAXDURABILITY, Player::ItemAddedQuestCheck(), m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, PERM_ENCHANTMENT_SLOT, Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT, Player::StoreItem(), TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), and Player::UpdateEnchantmentDurations().

◆ EffectSummonCritter()

void Spell::EffectSummonCritter ( SpellEffIndex  effIndex)

◆ EffectSummonObject()

void Spell::EffectSummonObject ( SpellEffIndex  effIndex)
4560{
4562 return;
4563
4564 uint32 gameobjectId = m_spellInfo->Effects[effIndex].MiscValue;
4565
4566 uint8 slot = 0;
4567 switch (m_spellInfo->Effects[effIndex].Effect)
4568 {
4570 slot = 0;
4571 break;
4573 slot = 1;
4574 break;
4576 slot = 2;
4577 break;
4579 slot = 3;
4580 break;
4581 default:
4582 return;
4583 }
4584
4585 if (m_caster)
4586 {
4587 ObjectGuid guid = m_caster->m_ObjectSlot[slot];
4588 if (guid)
4589 {
4590 if (GameObject* gameObject = m_caster->GetMap()->GetGameObject(guid))
4591 {
4592 // Recast case - null spell id to make auras not be removed on object remove from world
4593 if (m_spellInfo->Id == gameObject->GetSpellId())
4594 gameObject->SetSpellId(0);
4595 m_caster->RemoveGameObject(gameObject, true);
4596 }
4597 m_caster->m_ObjectSlot[slot].Clear();
4598 }
4599 }
4600
4601 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobjectId) ? new StaticTransport() : new GameObject();
4602
4603 float x, y, z;
4604 // If dest location if present
4605 if (m_targets.HasDst())
4606 destTarget->GetPosition(x, y, z);
4607 // Summon in random point all other units if location present
4608 else
4610
4611 Map* map = m_caster->GetMap();
4612 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobjectId, map, m_caster->GetPhaseMask(), x, y, z, m_caster->GetOrientation(), G3D::Quat(), 0, GO_STATE_READY))
4613 {
4614 delete pGameObj;
4615 return;
4616 }
4617
4618 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->GetLevel());
4619 int32 duration = m_spellInfo->GetDuration();
4620 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4621 pGameObj->SetSpellId(m_spellInfo->Id);
4622 m_caster->AddGameObject(pGameObj);
4623
4624 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4625
4626 map->AddToMap(pGameObj, true);
4627
4628 m_caster->m_ObjectSlot[slot] = pGameObj->GetGUID();
4629}
#define DEFAULT_WORLD_OBJECT_SIZE
Definition ObjectDefines.h:44
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT4
Definition SharedDefines.h:896
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT1
Definition SharedDefines.h:893
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT3
Definition SharedDefines.h:895
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT2
Definition SharedDefines.h:894
ObjectGuid m_ObjectSlot[MAX_GAMEOBJECT_SLOT]
Definition Unit.h:1998

References Unit::AddGameObject(), Map::AddToMap(), ObjectGuid::Clear(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), GameObject, Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Map::GetGameObject(), Object::GetGUID(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, m_caster, Unit::m_ObjectSlot, m_spellInfo, m_targets, Unit::RemoveGameObject(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_SUMMON_OBJECT_SLOT1, SPELL_EFFECT_SUMMON_OBJECT_SLOT2, SPELL_EFFECT_SUMMON_OBJECT_SLOT3, and SPELL_EFFECT_SUMMON_OBJECT_SLOT4.

◆ EffectSummonObjectWild()

void Spell::EffectSummonObjectWild ( SpellEffIndex  effIndex)
3730{
3732 return;
3733
3734 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
3735
3736 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
3737
3738 WorldObject* target = focusObject;
3739 if (!target)
3740 target = m_caster;
3741
3742 float x, y, z;
3743 if (m_targets.HasDst())
3744 destTarget->GetPosition(x, y, z);
3745 else
3747
3748 Map* map = target->GetMap();
3749
3750 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id, map, m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), G3D::Quat(), 100, GO_STATE_READY))
3751 {
3752 delete pGameObj;
3753 return;
3754 }
3755
3756 int32 duration = m_spellInfo->GetDuration();
3757
3758 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
3759 pGameObj->SetSpellId(m_spellInfo->Id);
3760
3761 ExecuteLogEffectSummonObject(effIndex, pGameObj);
3762
3763 // Wild object not have owner and check clickable by players
3764 map->AddToMap(pGameObj, true);
3765
3766 if (pGameObj->GetGoType() == GAMEOBJECT_TYPE_FLAGDROP)
3767 if (Player* player = m_caster->ToPlayer())
3768 if (Battleground* bg = player->GetBattleground())
3769 bg->SetDroppedFlagGUID(pGameObj->GetGUID(), player->GetTeamId() == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE);
3770
3771 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
3772 {
3773 linkedTrap->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS :0);
3774 linkedTrap->SetSpellId(m_spellInfo->Id);
3775 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
3776 }
3777}
@ GAMEOBJECT_TYPE_FLAGDROP
Definition SharedDefines.h:1597
@ TEAM_ALLIANCE
Definition SharedDefines.h:771
@ TEAM_HORDE
Definition SharedDefines.h:772
GameObject * GetLinkedTrap()
Definition GameObject.cpp:2716
GameobjectTypes GetGoType() const
Definition GameObject.h:202

References Map::AddToMap(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), focusObject, GameObject, GAMEOBJECT_TYPE_FLAGDROP, Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), GameObject::GetGoType(), Object::GetGUID(), GameObject::GetLinkedTrap(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, m_caster, m_spellInfo, m_targets, GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, TEAM_ALLIANCE, TEAM_HORDE, and Object::ToPlayer().

◆ EffectSummonPet()

void Spell::EffectSummonPet ( SpellEffIndex  effIndex)
3141{
3143 return;
3144
3145 if (!m_originalCaster)
3146 return;
3147
3148 uint32 petentry = m_spellInfo->Effects[effIndex].MiscValue;
3149 int32 duration = m_spellInfo->GetDuration();
3150
3151 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
3152 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
3153
3154 Player* owner = m_originalCaster->ToPlayer();
3155 if (!owner && m_originalCaster->ToCreature()->IsTotem())
3157
3158 if (!owner)
3159 {
3160 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(67);
3161 if (properties)
3162 {
3163 // Xinef: unsummon old guardian
3164 if (Guardian* oldPet = m_originalCaster->GetGuardianPet())
3165 oldPet->UnSummon();
3166 SummonGuardian(effIndex, petentry, properties, 1, false);
3167 }
3168 return;
3169 }
3170
3171 Pet* OldSummon = owner->GetPet();
3172
3173 // if pet requested type already exist
3174 if (OldSummon)
3175 {
3176 if (petentry == 0 || OldSummon->GetEntry() == petentry)
3177 {
3178 // pet in corpse state can't be summoned
3179 if (OldSummon->isDead())
3180 return;
3181
3182 ASSERT(OldSummon->GetMap() == owner->GetMap());
3183
3184 //OldSummon->GetMap()->Remove(OldSummon->ToCreature(), false);
3185
3186 float px, py, pz;
3187 owner->GetClosePoint(px, py, pz, OldSummon->GetObjectSize());
3188
3189 OldSummon->NearTeleportTo(px, py, pz, OldSummon->GetOrientation());
3190 OldSummon->UpdateObjectVisibility();
3191
3192 OldSummon->SetHealth(OldSummon->GetMaxHealth());
3193 OldSummon->SetPower(OldSummon->getPowerType(), OldSummon->GetMaxPower(OldSummon->getPowerType()));
3194 // notify player
3195 for (CreatureSpellCooldowns::const_iterator itr = OldSummon->m_CreatureSpellCooldowns.begin(); itr != OldSummon->m_CreatureSpellCooldowns.end(); ++itr)
3196 owner->SendClearCooldown(itr->first, OldSummon);
3197
3198 // actually clear cooldowns
3199 OldSummon->m_CreatureSpellCooldowns.clear();
3200 Unit::AuraApplicationMap& myAuras = OldSummon->GetAppliedAuras();
3201 for (Unit::AuraApplicationMap::iterator i = myAuras.begin(); i != myAuras.end();)
3202 {
3203 Aura const* aura = i->second->GetBase();
3204 if (!aura->IsPassive() && !OldSummon->IsPetAura(aura) && aura->CanBeSentToClient())
3205 OldSummon->RemoveAura(i);
3206 else
3207 ++i;
3208 }
3209 return;
3210 }
3211
3212 if (owner->IsPlayer())
3213 owner->ToPlayer()->RemovePet(OldSummon, PET_SAVE_NOT_IN_SLOT, false);
3214 else
3215 return;
3216 }
3217
3218 float x, y, z;
3219 owner->GetClosePoint(x, y, z, owner->GetObjectSize());
3220 Pet* pet = owner->SummonPet(petentry, x, y, z, owner->GetOrientation(), SUMMON_PET);
3221 if (!pet)
3222 return;
3223
3224 if (m_caster->IsCreature())
3225 {
3226 if (m_caster->ToCreature()->IsTotem())
3228 else
3230 }
3231
3233
3234 // Reset cooldowns
3236 {
3237 pet->m_CreatureSpellCooldowns.clear();
3238 owner->PetSpellInitialize();
3239 }
3240
3241 // Set health to max if new pet is summoned
3242 // in this function old pet is saved with current health eg. 20% and new one is loaded from db with same amount
3243 // pet should have full health
3244 pet->SetHealth(pet->GetMaxHealth());
3245
3246 // generate new name for summon pet
3247 std::string new_name = sObjectMgr->GeneratePetName(petentry);
3248 if (!new_name.empty())
3249 pet->SetName(new_name);
3250
3251 // ExecuteLogEffectSummonObject(effectInfo->EffectIndex, pet);
3252}
@ SPELLMOD_DURATION
Definition SpellDefines.h:77
@ REACT_DEFENSIVE
Definition Unit.h:550
@ REACT_AGGRESSIVE
Definition Unit.h:551
bool CanBeSentToClient() const
Definition SpellAuras.cpp:1137
CreatureSpellCooldowns m_CreatureSpellCooldowns
Definition Creature.h:255
void SetReactState(ReactStates state)
A creature can have 3 ReactStates : Agressive, Passive, Neutral.
Definition Creature.h:95
Definition TemporarySummon.h:96
void SendClearCooldown(uint32 spell_id, Unit *target)
Definition Player.cpp:14678
void SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const *properties, uint32 numSummons, bool personalSpawn)
Definition SpellEffects.cpp:5949
bool IsPetAura(Aura const *aura)
Definition Unit.cpp:17419
void UpdateObjectVisibility(bool forced=true, bool fromUpdate=false) override
Definition Unit.cpp:19227
Powers getPowerType() const
Definition Unit.h:1056
bool isDead() const
Definition Unit.h:1712
void SetName(std::string const &newname)
Definition Object.h:526
float GetObjectSize() const
Definition Object.cpp:2764

References ASSERT, Aura::CanBeSentToClient(), CLASS_CONTEXT_PET, CLASS_HUNTER, effectHandleMode, SpellInfo::Effects, Unit::GetAppliedAuras(), Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Object::GetEntry(), Unit::GetGuardianPet(), WorldObject::GetMap(), Unit::GetMaxHealth(), Unit::GetMaxPower(), WorldObject::GetObjectSize(), Position::GetOrientation(), Player::GetPet(), Unit::getPowerType(), Unit::GetSpellModOwner(), SpellInfo::Id, Player::IsClass(), Object::IsCreature(), Unit::isDead(), Aura::IsPassive(), Unit::IsPetAura(), Object::IsPlayer(), Unit::IsTotem(), m_caster, Creature::m_CreatureSpellCooldowns, m_originalCaster, m_spellInfo, Unit::NearTeleportTo(), PET_SAVE_NOT_IN_SLOT, Player::PetSpellInitialize(), REACT_AGGRESSIVE, REACT_DEFENSIVE, Unit::RemoveAura(), Player::RemovePet(), Player::SendClearCooldown(), Unit::SetHealth(), WorldObject::SetName(), Unit::SetPower(), Creature::SetReactState(), Unit::SetUInt32Value(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, SPELLMOD_DURATION, sSummonPropertiesStore, SUMMON_PET, SummonGuardian(), Player::SummonPet(), Object::ToCreature(), Object::ToPlayer(), UNIT_CREATED_BY_SPELL, and Unit::UpdateObjectVisibility().

◆ EffectSummonPlayer()

void Spell::EffectSummonPlayer ( SpellEffIndex  effIndex)
4213{
4214 // workaround - this effect should not use target map
4216 return;
4217
4218 if (!unitTarget)
4219 return;
4220
4221 Player* player = unitTarget->ToPlayer();
4222 if (!player)
4223 {
4224 return;
4225 }
4226
4227 // Evil Twin (ignore player summon, but hide this for summoner)
4228 // Xinef: Unit Target may be on other map!!!, Need workaround
4229 if (unitTarget->HasAura(23445))
4230 return;
4231
4232 float x, y, z;
4233 m_caster->GetPosition(x, y, z);
4234
4235 player->SetSummonPoint(m_caster->GetMapId(), x, y, z);
4236
4237 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
4238 data << m_caster->GetGUID(); // summoner guid
4239 data << uint32(m_caster->GetZoneId()); // summoner zone
4240 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
4241 player->GetSession()->SendPacket(&data);
4242}
#define MAX_PLAYER_SUMMON_DELAY
Definition Player.h:925
void SetSummonPoint(uint32 mapid, float x, float y, float z, uint32 delay=0, bool asSpectator=false)
Definition Player.cpp:16355
@ SMSG_SUMMON_REQUEST
Definition Opcodes.h:713

References effectHandleMode, Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPosition(), Player::GetSession(), WorldObject::GetZoneId(), Unit::HasAura(), IN_MILLISECONDS, m_caster, MAX_PLAYER_SUMMON_DELAY, WorldSession::SendPacket(), Player::SetSummonPoint(), SMSG_SUMMON_REQUEST, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSummonRaFFriend()

void Spell::EffectSummonRaFFriend ( SpellEffIndex  effIndex)
6318{
6320 return;
6321
6322 if (!m_caster->IsPlayer())
6323 return;
6324
6325 if (!unitTarget)
6326 return;
6327
6328 Player* player = unitTarget->ToPlayer();
6329 if (!player)
6330 {
6331 return;
6332 }
6333
6334 float x, y, z;
6335 m_caster->GetPosition(x, y, z);
6337 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
6338 data << m_caster->GetGUID();
6339 data << uint32(m_caster->GetZoneId());
6340 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
6341 player->GetSession()->SendPacket(&data);
6342}

References effectHandleMode, Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPosition(), Player::GetSession(), WorldObject::GetZoneId(), IN_MILLISECONDS, Object::IsPlayer(), m_caster, MAX_PLAYER_SUMMON_DELAY, WorldSession::SendPacket(), Player::SetSummonPoint(), SMSG_SUMMON_REQUEST, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSummonType()

void Spell::EffectSummonType ( SpellEffIndex  effIndex)
2330{
2332 return;
2333
2334 uint32 entry = m_spellInfo->Effects[effIndex].MiscValue;
2335
2336 if (m_spellValue->MiscVal[effIndex])
2337 entry = m_spellValue->MiscVal[effIndex];
2338
2339 if (!entry)
2340 return;
2341
2342 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[effIndex].MiscValueB);
2343 if (!properties)
2344 {
2345 LOG_ERROR("spells.effect", "EffectSummonType: Unhandled summon type {}", m_spellInfo->Effects[effIndex].MiscValueB);
2346 return;
2347 }
2348
2349 if (!m_originalCaster)
2350 return;
2351
2352 bool personalSpawn = (properties->Flags & SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER) != 0;
2353 int32 duration = m_spellInfo->GetDuration();
2354 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
2355 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
2356
2357 TempSummon* summon = nullptr;
2358
2359 // determine how many units should be summoned
2360 uint32 numSummons;
2361
2362 // some spells need to summon many units, for those spells number of summons is stored in effect value
2363 // however so far noone found a generic check to find all of those (there's no related data in summonproperties.dbc
2364 // and in spell attributes, possibly we need to add a table for those)
2365 // so here's a list of MiscValueB values, which is currently most generic check
2366 switch (properties->Id)
2367 {
2368 case 64:
2369 case 61:
2370 case 1101:
2371 case 66:
2372 case 648:
2373 case 2301:
2374 case 1061:
2375 case 1261:
2376 case 629:
2377 case 181:
2378 case 715:
2379 case 1562:
2380 case 833:
2381 case 1161:
2382 case 713: // xinef, bloodworms
2383 numSummons = (damage > 0) ? damage : 1;
2384 break;
2385 default:
2386 numSummons = 1;
2387 break;
2388 }
2389
2390 switch (properties->Category)
2391 {
2395 if (properties->Flags & 512)
2396 {
2397 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2398 break;
2399 }
2400 switch (properties->Type)
2401 {
2402 case SUMMON_TYPE_PET:
2405 case SUMMON_TYPE_MINION:
2406 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2407 break;
2408 // Summons a vehicle, but doesn't force anyone to enter it (see SUMMON_CATEGORY_VEHICLE)
2411 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2412 break;
2414 case SUMMON_TYPE_TOTEM:
2415 {
2416 // protection code
2417 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2418 if (!summon || !summon->IsTotem())
2419 return;
2420
2421 // Mana Tide Totem
2422 if (m_spellInfo->Id == 16190)
2424
2425 if (damage && properties->Type != SUMMON_TYPE_LIGHTWELL) // Health set in script for lightwell
2426 {
2427 summon->SetMaxHealth(damage);
2428 summon->SetHealth(damage);
2429 }
2430 break;
2431 }
2432 case SUMMON_TYPE_JEEVES:
2434 {
2435 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2436 if (!summon || !summon->HasUnitTypeMask(UNIT_MASK_MINION))
2437 return;
2438
2439 summon->SelectLevel(); // some summoned creaters have different from 1 DB data for level/hp
2441
2442 summon->SetImmuneToAll(true);
2444
2445 // Xinef: Pet can have some auras in creature_addon or in scripts, do not remove them instantly
2446 //summon->AI()->EnterEvadeMode();
2447 if (properties->Type != SUMMON_TYPE_JEEVES)
2448 {
2449 summon->GetMotionMaster()->Clear(false);
2451 }
2452 break;
2453 }
2454 default:
2455 {
2456 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2457
2458 TempSummonType summonType = (duration <= 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
2459
2460 for (uint32 count = 0; count < numSummons; ++count)
2461 {
2462 Position pos;
2463 if (count == 0)
2464 pos = *destTarget;
2465 else
2466 // randomize position for multiple summons
2467 pos = m_caster->GetRandomPoint(*destTarget, radius);
2468
2469 summon = m_originalCaster->SummonCreature(entry, pos, summonType, duration, 0, nullptr, personalSpawn);
2470 if (!summon)
2471 continue;
2472
2473 summon->SetTempSummonType(summonType);
2474
2475 if (properties->Category == SUMMON_CATEGORY_ALLY)
2476 {
2479 }
2480
2481 ExecuteLogEffectSummonObject(effIndex, summon);
2482 }
2483 return;
2484 }
2485 }//switch
2486 break;
2488 // Xinef: SummonGuardian function can summon a few npcs of same type, remove old summons with same entry here
2489 if (m_originalCaster)
2491 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2492 break;
2494 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2495 break;
2497 // Summoning spells (usually triggered by npc_spellclick) that spawn a vehicle and that cause the clicker
2498 // to cast a ride vehicle spell on the summoned unit.
2499 //float x, y, z;
2500 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
2501 // xinef: vehicles summoned in air, eg. Cold Hearted quest
2502 if (std::fabs(m_caster->GetPositionZ() - destTarget->GetPositionZ()) > 6.0f)
2504
2505 summon = m_originalCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_caster, m_spellInfo->Id, 0, personalSpawn);
2506 if (!summon || !summon->IsVehicle())
2507 return;
2508
2509 // The spell that this effect will trigger. It has SPELL_AURA_CONTROL_VEHICLE
2511 int32 basePoints = m_spellInfo->Effects[effIndex].CalcValue();
2512 if (basePoints > 1) // xinef: some summoning spells have value 1 - indicates vehicle seat
2513 {
2514 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(basePoints);
2515 if (spellInfo && spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
2516 spellId = spellInfo->Id;
2517 }
2518
2519 // xinef: if we have small value, it indicates seat position
2520 if (basePoints > 0 && basePoints < MAX_VEHICLE_SEATS)
2521 m_originalCaster->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, basePoints, summon, true);
2522 else
2523 m_originalCaster->CastSpell(summon, spellId, true);
2524
2525 // xinef: i think this is wrong, found only 2 vehicles with faction override and one of them should inherit caster faction...
2526 //uint32 faction = properties->Faction;
2527 //if (!faction)
2528 uint32 faction = m_originalCaster->GetFaction();
2529
2530 summon->SetFaction(faction);
2531 break;
2532 }
2533
2534 if (summon)
2535 {
2537 ExecuteLogEffectSummonObject(effIndex, summon);
2538 }
2539}
@ SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER
Definition DBCEnums.h:428
#define MAX_VEHICLE_SEATS
Definition DBCStructure.h:2025
@ MOTION_SLOT_ACTIVE
Definition MotionMaster.h:64
TempSummonType
Definition Object.h:47
@ TEMPSUMMON_DEAD_DESPAWN
Definition Object.h:54
@ SUMMON_TYPE_VEHICLE2
Definition SharedDefines.h:3554
@ SUMMON_TYPE_LIGHTWELL
Definition SharedDefines.h:3555
@ SUMMON_TYPE_MINION
Definition SharedDefines.h:3547
@ SUMMON_TYPE_GUARDIAN
Definition SharedDefines.h:3546
@ SUMMON_TYPE_JEEVES
Definition SharedDefines.h:3556
@ SUMMON_TYPE_PET
Definition SharedDefines.h:3545
@ SUMMON_TYPE_TOTEM
Definition SharedDefines.h:3548
@ SUMMON_TYPE_VEHICLE
Definition SharedDefines.h:3553
@ SUMMON_TYPE_MINIPET
Definition SharedDefines.h:3549
@ SUMMON_TYPE_GUARDIAN2
Definition SharedDefines.h:3550
@ SUMMON_CATEGORY_VEHICLE
Definition SharedDefines.h:3537
@ SUMMON_CATEGORY_ALLY
Definition SharedDefines.h:3534
@ SUMMON_CATEGORY_WILD
Definition SharedDefines.h:3533
@ SUMMON_CATEGORY_UNK
Definition SharedDefines.h:3538
@ SPELL_AURA_CONTROL_VEHICLE
Definition SpellAuraDefines.h:299
@ UNIT_MASK_MINION
Definition UnitDefines.h:157
NPCFlags
Non Player Character flags.
Definition UnitDefines.h:315
@ REACT_PASSIVE
Definition Unit.h:549
@ VEHICLE_SPELL_RIDE_HARDCODED
Definition VehicleDefines.h:52
void SelectLevel(bool changelevel=true)
Definition Creature.cpp:1521
TempSummon * SummonCreature(uint32 entry, Position const &pos, SummonPropertiesEntry const *properties=nullptr, uint32 duration=0, WorldObject *summoner=nullptr, uint32 spellId=0, uint32 vehId=0, bool visibleBySummonerOnly=false)
Definition Object.cpp:2140
void MoveFollow(Unit *target, float dist, float angle, MovementSlot slot=MOTION_SLOT_ACTIVE, bool inheritWalkState=true, bool inheritSpeed=true)
The unit will follow this target. Doesn't work with UNIT_FLAG_DISABLE_MOVE.
Definition MotionMaster.cpp:444
void Clear(bool reset=true)
Definition MotionMaster.h:167
void SetTempSummonType(TempSummonType type)
Definition TemporarySummon.cpp:282
void SetFaction(uint32 faction)
Definition Unit.cpp:10126
virtual float GetFollowAngle() const
Definition Unit.h:1812
void SetOwnerGUID(ObjectGuid owner)
Definition Unit.cpp:10668
uint32 HasUnitTypeMask(uint32 mask) const
Definition Unit.h:696
void SetMaxHealth(uint32 val)
Definition Unit.cpp:15629
void SetCreatorGUID(ObjectGuid creator)
Definition Unit.h:671
void ReplaceAllNpcFlags(NPCFlags flags)
Definition Unit.h:721
void RemoveAllMinionsByEntry(uint32 entry)
Definition Unit.cpp:10958
void SetImmuneToAll(bool apply, bool keepCombat=false)
Definition Unit.h:871
void GetRandomPoint(const Position &srcPos, float distance, float &rand_x, float &rand_y, float &rand_z) const
Definition Object.cpp:1507
uint32 npcflag
Definition CreatureData.h:199
uint32 MiscVal[MAX_SPELL_EFFECTS]
Definition Spell.h:228
uint32 Flags
Definition DBCStructure.h:1916
uint32 Type
Definition DBCStructure.h:1914
uint32 Id
Definition DBCStructure.h:1911

References Unit::CastCustomSpell(), Unit::CastSpell(), SummonPropertiesEntry::Category, MotionMaster::Clear(), Unit::CountPctFromMaxHealth(), damage, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), SummonPropertiesEntry::Flags, Creature::GetCreatureTemplate(), SpellInfo::GetDuration(), Unit::GetFaction(), Unit::GetFollowAngle(), Object::GetGUID(), WorldObject::GetMap(), Unit::GetMotionMaster(), Position::GetPositionZ(), WorldObject::GetRandomPoint(), Unit::GetSpellModOwner(), SpellInfo::HasAura(), Unit::HasUnitTypeMask(), SpellInfo::Id, SummonPropertiesEntry::Id, Unit::IsTotem(), Unit::IsVehicle(), LOG_ERROR, m_caster, m_originalCaster, Position::m_positionZ, m_spellInfo, m_spellValue, MAX_VEHICLE_SEATS, SpellValue::MiscVal, MOTION_SLOT_ACTIVE, MotionMaster::MoveFollow(), CreatureTemplate::npcflag, PET_FOLLOW_DIST, REACT_PASSIVE, Unit::RemoveAllMinionsByEntry(), Unit::ReplaceAllNpcFlags(), Creature::SelectLevel(), Unit::SetCreatorGUID(), Unit::SetFaction(), Unit::SetHealth(), Unit::SetImmuneToAll(), Unit::SetMaxHealth(), Unit::SetOwnerGUID(), Creature::SetReactState(), TempSummon::SetTempSummonType(), SPELL_AURA_CONTROL_VEHICLE, SPELL_EFFECT_HANDLE_HIT, SPELLMOD_DURATION, SPELLVALUE_BASE_POINT0, sSpellMgr, sSummonPropertiesStore, SUMMON_CATEGORY_ALLY, SUMMON_CATEGORY_PET, SUMMON_CATEGORY_PUPPET, SUMMON_CATEGORY_UNK, SUMMON_CATEGORY_VEHICLE, SUMMON_CATEGORY_WILD, SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER, SUMMON_TYPE_GUARDIAN, SUMMON_TYPE_GUARDIAN2, SUMMON_TYPE_JEEVES, SUMMON_TYPE_LIGHTWELL, SUMMON_TYPE_MINION, SUMMON_TYPE_MINIPET, SUMMON_TYPE_PET, SUMMON_TYPE_TOTEM, SUMMON_TYPE_VEHICLE, SUMMON_TYPE_VEHICLE2, Map::SummonCreature(), WorldObject::SummonCreature(), SummonGuardian(), TEMPSUMMON_DEAD_DESPAWN, TEMPSUMMON_TIMED_DESPAWN, SummonPropertiesEntry::Type, UNIT_MASK_MINION, and VEHICLE_SPELL_RIDE_HARDCODED.

◆ EffectTameCreature()

void Spell::EffectTameCreature ( SpellEffIndex  effIndex)
3085{
3087 return;
3088
3089 if (m_caster->GetPetGUID())
3090 return;
3091
3092 if (!unitTarget)
3093 return;
3094
3095 if (!unitTarget->IsCreature())
3096 return;
3097
3098 Creature* creatureTarget = unitTarget->ToCreature();
3099
3100 if (creatureTarget->IsPet())
3101 return;
3102
3104 return;
3105
3106 // cast finish successfully
3107 //SendChannelUpdate(0);
3108 finish();
3109
3110 Pet* pet = m_caster->CreateTamedPetFrom(creatureTarget, m_spellInfo->Id);
3111 if (!pet) // in very specific state like near world end/etc.
3112 return;
3113
3114 // "kill" original creature
3115 creatureTarget->DespawnOrUnsummon();
3116
3117 uint8 level = (creatureTarget->GetLevel() < (m_caster->GetLevel() - 5)) ? (m_caster->GetLevel() - 5) : creatureTarget->GetLevel();
3118
3119 // prepare visual effect for levelup
3120 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
3121
3122 // add to world
3123 pet->GetMap()->AddToMap(pet->ToCreature(), true);
3124
3125 // visual effect for levelup
3126 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
3127
3128 // caster have pet now
3129 m_caster->SetMinion(pet, true);
3130
3131 pet->InitTalentForLevel();
3132
3133 if (m_caster->IsPlayer())
3134 {
3137 }
3138}
@ UNIT_FIELD_LEVEL
Definition UpdateFields.h:114

References Map::AddToMap(), CLASS_CONTEXT_PET, CLASS_HUNTER, Unit::CreateTamedPetFrom(), Creature::DespawnOrUnsummon(), effectHandleMode, finish(), Unit::GetLevel(), WorldObject::GetMap(), Unit::GetPetGUID(), SpellInfo::Id, Pet::InitTalentForLevel(), Unit::IsClass(), Object::IsCreature(), Unit::IsPet(), Object::IsPlayer(), m_caster, m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), Unit::SetMinion(), Unit::SetUInt32Value(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), UNIT_FIELD_LEVEL, and unitTarget.

◆ EffectTaunt()

void Spell::EffectTaunt ( SpellEffIndex  effIndex)
3281{
3283 return;
3284
3285 if (!unitTarget)
3286 return;
3287
3288 // xinef: Hand of Reckoning, cast before checing canhavethreatlist. fixes damage against pets
3289 if (m_spellInfo->Id == 62124 && unitTarget->GetVictim() != m_caster)
3290 {
3291 m_caster->CastSpell(unitTarget, 67485, true);
3293 }
3294
3295 // this effect use before aura Taunt apply for prevent taunt already attacking target
3296 // for spell as marked "non effective at already attacking target"
3298 {
3300 return;
3301 }
3302
3304 {
3305 // Also use this effect to set the taunter's threat to the taunted creature's highest value
3306 float myThreat = unitTarget->GetThreatMgr().GetThreat(m_caster);
3308 if (topThreat > myThreat)
3309 unitTarget->GetThreatMgr().DoAddThreat(m_caster, topThreat - myThreat);
3310
3311 //Set aggro victim to caster
3313 unitTarget->GetThreatMgr().setCurrentVictim(forcedVictim);
3314 }
3315}
@ SPELL_AURA_MOD_TAUNT
Definition SpellAuraDefines.h:74
Definition ThreatMgr.h:48
float GetThreat() const
Definition ThreatMgr.h:62
HostileReference * getMostHated() const
Definition ThreatMgr.h:168
HostileReference * getReferenceByTarget(Unit const *victim) const
Definition ThreatMgr.cpp:261
bool empty() const
Definition ThreatMgr.h:163
void setCurrentVictim(HostileReference *hostileRef)
Definition ThreatMgr.cpp:572
void DoAddThreat(Unit *victim, float threat)
Definition ThreatMgr.cpp:453
float GetThreat(Unit *victim, bool alsoSearchOfflineList=false)
Definition ThreatMgr.cpp:525
ThreatContainer & GetOnlineContainer()
Definition ThreatMgr.h:275
bool CanHaveThreatList(bool skipAliveCheck=false) const
Definition Unit.cpp:14715

References Unit::CanHaveThreatList(), Unit::CastSpell(), Unit::CombatStart(), ThreatMgr::DoAddThreat(), effectHandleMode, ThreatContainer::empty(), ThreatContainer::getMostHated(), ThreatMgr::GetOnlineContainer(), ThreatContainer::getReferenceByTarget(), HostileReference::GetThreat(), ThreatMgr::GetThreat(), Unit::GetThreatMgr(), Unit::GetVictim(), SpellInfo::HasAura(), SpellInfo::Id, m_caster, m_spellInfo, SendCastResult(), ThreatMgr::setCurrentVictim(), SPELL_AURA_MOD_TAUNT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_FAILED_DONT_REPORT, and unitTarget.

◆ EffectTeleportUnits()

void Spell::EffectTeleportUnits ( SpellEffIndex  effIndex)
1181{
1183 return;
1184
1185 if (!unitTarget || unitTarget->IsInFlight())
1186 return;
1187
1188 if (unitTarget->IsPlayer())
1189 {
1190 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
1191 }
1192
1193 // Pre effects
1194 switch (m_spellInfo->Id)
1195 {
1196 case 70746: // Teleport Into Sunwell (for Battered Hilt)
1197 if (Player* target = unitTarget->ToPlayer())
1198 {
1199 uint32 mapid = destTarget->GetMapId();
1200 float x, y, z, orientation;
1201 destTarget->GetPosition(x, y, z, orientation);
1202 target->TeleportTo(mapid, x, y, z, orientation, TELE_TO_GM_MODE); // skip PlayerCannotEnter check
1203 }
1204 return;
1205 }
1206
1207 // If not exist data for dest location - return
1208 if (!m_targets.HasDst())
1209 {
1210 LOG_ERROR("spells.effect", "Spell::EffectTeleportUnits - does not have destination for spell ID {}\n", m_spellInfo->Id);
1211 return;
1212 }
1213
1214 // Init dest coordinates
1215 uint32 mapid = destTarget->GetMapId();
1216 if (mapid == MAPID_INVALID)
1217 mapid = unitTarget->GetMapId();
1218 float x, y, z, orientation;
1219 destTarget->GetPosition(x, y, z, orientation);
1220 if (!orientation && m_targets.GetUnitTarget())
1221 orientation = m_targets.GetUnitTarget()->GetOrientation();
1222 LOG_DEBUG("spells.aura", "Spell::EffectTeleportUnits - teleport unit to {} {} {} {} {}\n", mapid, x, y, z, orientation);
1223
1224 if (mapid == unitTarget->GetMapId())
1225 {
1226 if (unitTarget->GetVehicleKit()) // we are vehicle!
1227 unitTarget->GetVehicleKit()->TeleportVehicle(x, y, z, orientation);
1228 else
1229 {
1231 unitTarget->NearTeleportTo(x, y, z, orientation, unitTarget == m_caster, false, withPet, true);
1232 if (unitTarget->IsPlayer()) // pussywizard: for units it's done inside NearTeleportTo
1234 }
1235 }
1236 else if (unitTarget->IsPlayer())
1237 unitTarget->ToPlayer()->TeleportTo(mapid, x, y, z, orientation, unitTarget == m_caster ? TELE_TO_SPELL : 0);
1238 else
1239 {
1240 LOG_ERROR("spells.effect", "Spell::EffectTeleportUnits - spellId {} attempted to teleport creature to a different map.", m_spellInfo->Id);
1241 return;
1242 }
1243
1244 // post effects for TARGET_DEST_DB
1245 switch (m_spellInfo->Id)
1246 {
1247 // Dimensional Ripper - Everlook
1248 case 23442:
1249 {
1250 int32 r = irand(0, 119);
1251 if (r >= 70) // 7/12 success
1252 {
1253 if (r < 100) // 4/12 evil twin
1254 m_caster->CastSpell(m_caster, 23445, true);
1255 else // 1/12 fire
1256 m_caster->CastSpell(m_caster, 23449, true);
1257 }
1258 return;
1259 }
1260 // Ultrasafe Transporter: Toshley's Station
1261 case 36941:
1262 {
1263 if (roll_chance_i(50)) // 50% success
1264 {
1265 int32 rand_eff = urand(1, 7);
1266 switch (rand_eff)
1267 {
1268 case 1:
1269 // soul split - evil
1270 m_caster->CastSpell(m_caster, 36900, true);
1271 break;
1272 case 2:
1273 // soul split - good
1274 m_caster->CastSpell(m_caster, 36901, true);
1275 break;
1276 case 3:
1277 // Increase the size
1278 m_caster->CastSpell(m_caster, 36895, true);
1279 break;
1280 case 4:
1281 // Decrease the size
1282 m_caster->CastSpell(m_caster, 36893, true);
1283 break;
1284 case 5:
1285 // Transform
1286 {
1288 m_caster->CastSpell(m_caster, 36897, true);
1289 else
1290 m_caster->CastSpell(m_caster, 36899, true);
1291 break;
1292 }
1293 case 6:
1294 // chicken
1295 m_caster->CastSpell(m_caster, 36940, true);
1296 break;
1297 case 7:
1298 // evil twin
1299 m_caster->CastSpell(m_caster, 23445, true);
1300 break;
1301 }
1302 }
1303 return;
1304 }
1305 }
1306}
@ TELE_TO_SPELL
Definition Player.h:821
@ TELE_TO_GM_MODE
Definition Player.h:817
#define MAPID_INVALID
Definition Position.h:252
TeamId GetTeamId(bool original=false) const
Definition Player.h:2115
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options=0, Unit *target=nullptr, bool newInstance=false)
Definition Player.cpp:1345
Vehicle * GetVehicleKit() const
Definition Unit.h:1841
void TeleportVehicle(float x, float y, float z, float ang)
Definition Vehicle.cpp:563

References Unit::CastSpell(), destTarget, effectHandleMode, Position::GetExactDist(), WorldObject::GetMap(), WorldLocation::GetMapId(), Position::GetOrientation(), Position::GetPosition(), Player::GetTeamId(), SpellCastTargets::GetUnitTarget(), Unit::GetVehicleKit(), SpellCastTargets::HasDst(), SpellInfo::Id, irand(), Map::IsDungeon(), Unit::IsInFlight(), Object::IsPlayer(), LOG_DEBUG, LOG_ERROR, m_caster, m_spellInfo, m_targets, MAPID_INVALID, Unit::NearTeleportTo(), roll_chance_i(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SpellInfo::SpellFamilyName, sScriptMgr, TEAM_ALLIANCE, TELE_TO_GM_MODE, TELE_TO_SPELL, Player::TeleportTo(), Vehicle::TeleportVehicle(), Object::ToPlayer(), unitTarget, Unit::UpdateObjectVisibility(), and urand().

◆ EffectTeleUnitsFaceCaster()

◆ EffectThreat()

void Spell::EffectThreat ( SpellEffIndex  effIndex)
3655{
3657 return;
3658
3659 if (!unitTarget || !unitTarget->IsAlive() || !m_caster->IsAlive())
3660 return;
3661
3662 // xinef: skip if target cannot have threat list or caster is friendly (ghoul leap)
3664 return;
3665
3667}
void AddThreat(Unit *victim, float fThreat, SpellSchoolMask schoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *threatSpell=nullptr)
Definition Unit.cpp:14754

References Unit::AddThreat(), Unit::CanHaveThreatList(), damage, effectHandleMode, Unit::IsAlive(), Unit::IsFriendlyTo(), m_caster, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectTitanGrip()

void Spell::EffectTitanGrip ( SpellEffIndex  effIndex)
5883{
5885 return;
5886
5887 if (m_caster->IsPlayer())
5888 {
5889 if (Aura* aur = m_caster->GetAura(49152))
5890 aur->RecalculateAmountOfEffects();
5891 else
5892 m_caster->CastSpell(unitTarget, 49152, true); // damage reduction
5893
5895 }
5896}
void SetCanTitanGrip(bool value)
Definition Player.cpp:13167

References Unit::CastSpell(), effectHandleMode, Unit::GetAura(), Object::IsPlayer(), m_caster, Player::SetCanTitanGrip(), SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), and unitTarget.

◆ EffectTradeSkill()

void Spell::EffectTradeSkill ( SpellEffIndex  effIndex)
2822{
2824 return;
2825
2826 if (!m_caster->IsPlayer())
2827 return;
2828 // uint32 skillid = m_spellInfo->Effects[i].MiscValue;
2829 // uint16 skillmax = unitTarget->ToPlayer()->(skillid);
2830 // m_caster->ToPlayer()->SetSkill(skillid, skillval?skillval:1, skillmax+75);
2831}

References effectHandleMode, Object::IsPlayer(), m_caster, and SPELL_EFFECT_HANDLE_HIT.

◆ EffectTransmitted()

void Spell::EffectTransmitted ( SpellEffIndex  effIndex)
5353{
5355 return;
5356
5357 uint32 name_id = m_spellInfo->Effects[effIndex].MiscValue;
5358
5359 GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(name_id);
5360
5361 if (!goinfo)
5362 {
5363 LOG_ERROR("sql.sql", "Gameobject (Entry: {}) not exist and not created at spell (ID: {}) cast", name_id, m_spellInfo->Id);
5364 return;
5365 }
5366
5367 float fx, fy, fz;
5368
5369 if (m_targets.HasDst())
5370 destTarget->GetPosition(fx, fy, fz);
5371 //FIXME: this can be better check for most objects but still hack
5372 else if (m_spellInfo->Effects[effIndex].HasRadius() && m_spellInfo->Speed == 0)
5373 {
5374 float dis = m_spellInfo->Effects[effIndex].CalcRadius(m_originalCaster);
5376 }
5377 else
5378 {
5379 //GO is always friendly to it's creator, get range for friends
5380 float min_dis = m_spellInfo->GetMinRange(true);
5381 float max_dis = m_spellInfo->GetMaxRange(true);
5382 float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
5383
5385 }
5386
5387 // Seaforium charge
5388 if (m_spellInfo->Id == 52410 || m_spellInfo->Id == 66268 || m_spellInfo->Id == 66674) // SotA / IoC / IoC Huge
5389 {
5390 fx = m_caster->GetPositionX();
5391 fy = m_caster->GetPositionY();
5392 fz = m_caster->GetPositionZ();
5393 }
5394
5395 Map* cMap = m_caster->GetMap();
5396
5397 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(name_id) ? new StaticTransport() : new GameObject();
5398
5399 if (!pGameObj->Create(cMap->GenerateLowGuid<HighGuid::GameObject>(), name_id, cMap, m_caster->GetPhaseMask(), fx, fy, fz, m_caster->GetOrientation(), G3D::Quat(), 100, GO_STATE_READY))
5400 {
5401 delete pGameObj;
5402 return;
5403 }
5404
5405 int32 duration = m_spellInfo->GetDuration();
5406
5407 switch (goinfo->type)
5408 {
5410 {
5412 m_caster->AddGameObject(pGameObj); // will removed at spell cancel
5413
5414 // end time of range when possible catch fish (FISHING_BOBBER_READY_TIME..GetDuration(m_spellInfo))
5415 // start time == fish-FISHING_BOBBER_READY_TIME (0..GetDuration(m_spellInfo)-FISHING_BOBBER_READY_TIME)
5416 int32 lastSec = 0;
5417 switch (urand(0, 2))
5418 {
5419 case 0:
5420 lastSec = 3;
5421 break;
5422 case 1:
5423 lastSec = 7;
5424 break;
5425 case 2:
5426 lastSec = 13;
5427 break;
5428 }
5429
5430 // Duration of the fishing bobber can't be higher than the Fishing channeling duration
5431 duration = std::min(duration, duration - lastSec*IN_MILLISECONDS + FISHING_BOBBER_READY_TIME*IN_MILLISECONDS);
5432
5433 break;
5434 }
5436 {
5437 if (m_caster->IsPlayer())
5438 {
5439 pGameObj->AddUniqueUse(m_caster->ToPlayer());
5440 m_caster->AddGameObject(pGameObj); // will be removed at spell cancel
5441 }
5442 break;
5443 }
5444 case GAMEOBJECT_TYPE_DUEL_ARBITER: // 52991
5445 m_caster->AddGameObject(pGameObj);
5446 break;
5449 default:
5450 break;
5451 }
5452
5453 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
5454
5455 pGameObj->SetOwnerGUID(m_caster->GetGUID());
5456
5457 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->GetLevel());
5458 pGameObj->SetSpellId(m_spellInfo->Id);
5459
5460 ExecuteLogEffectSummonObject(effIndex, pGameObj);
5461
5462 LOG_DEBUG("spells.effect", "AddObject at SpellEfects.cpp EffectTransmitted");
5463 //m_caster->AddGameObject(pGameObj);
5464 //m_ObjToDel.push_back(pGameObj);
5465
5466 cMap->AddToMap(pGameObj, true);
5467
5468 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
5469 {
5470 linkedTrap->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
5471 linkedTrap->SetSpellId(m_spellInfo->Id);
5472 linkedTrap->SetOwnerGUID(m_caster->GetGUID());
5473
5474 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
5475 }
5476
5477 if (Player* player = m_caster->ToPlayer())
5478 {
5479 player->SetCanTeleport(true);
5480 }
5481}
#define FISHING_BOBBER_READY_TIME
Definition GameObject.h:117
@ GAMEOBJECT_TYPE_DUEL_ARBITER
Definition SharedDefines.h:1587
@ GAMEOBJECT_TYPE_SUMMONING_RITUAL
Definition SharedDefines.h:1589
@ GAMEOBJECT_TYPE_CHEST
Definition SharedDefines.h:1574
@ GAMEOBJECT_TYPE_FISHINGHOLE
Definition SharedDefines.h:1596
@ GAMEOBJECT_TYPE_FISHINGNODE
Definition SharedDefines.h:1588
@ UNIT_FIELD_CHANNEL_OBJECT
Definition UpdateFields.h:93
void SetOwnerGUID(ObjectGuid owner)
Definition GameObject.h:163
void AddUniqueUse(Player *player)
Definition GameObject.cpp:926
float GetMinRange(bool positive=false) const
Definition SpellInfo.cpp:2321

References Unit::AddGameObject(), Map::AddToMap(), GameObject::AddUniqueUse(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), FISHING_BOBBER_READY_TIME, GameObject, GAMEOBJECT_TYPE_CHEST, GAMEOBJECT_TYPE_DUEL_ARBITER, GAMEOBJECT_TYPE_FISHINGHOLE, GAMEOBJECT_TYPE_FISHINGNODE, GAMEOBJECT_TYPE_SUMMONING_RITUAL, Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Object::GetGUID(), GameObject::GetLinkedTrap(), WorldObject::GetMap(), SpellInfo::GetMaxRange(), SpellInfo::GetMinRange(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, Object::IsPlayer(), LOG_DEBUG, LOG_ERROR, m_caster, m_originalCaster, m_spellInfo, m_targets, rand_norm(), Object::SetGuidValue(), GameObject::SetOwnerGUID(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SpellInfo::Speed, SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), GameObjectTemplate::type, UNIT_FIELD_CHANNEL_OBJECT, and urand().

◆ EffectTriggerMissileSpell()

void Spell::EffectTriggerMissileSpell ( SpellEffIndex  effIndex)
943{
946 return;
947
948 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
949
950 // normal case
951 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
952 if (!spellInfo)
953 {
954 LOG_DEBUG("spells.aura", "Spell::EffectTriggerMissileSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
955 return;
956 }
957
958 SpellCastTargets targets;
960 {
961 if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex))
962 return;
963 targets.SetUnitTarget(unitTarget);
964 }
965 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
966 {
967 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
968 return;
969
971 targets.SetDst(m_targets);
972
973 targets.SetUnitTarget(m_caster);
974 }
975
976 CustomSpellValues values;
977 // set basepoints for trigger with value effect
979 {
980 // maybe need to set value only when basepoints == 0?
984 }
985
986 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
987 if (m_caster->IsPlayer() && spellInfo->CategoryRecoveryTime && m_spellInfo->GetCategory() == spellInfo->GetCategory())
988 {
989 m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
990 }
991
992 // original caster guid only for GO cast
993 m_caster->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK, nullptr, nullptr, m_originalCasterGUID);
994}
@ SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE
Definition SharedDefines.h:937
@ TARGET_FLAG_DEST_LOCATION
Definition SpellInfo.h:53
bool NeedsToBeTriggeredByCaster(SpellInfo const *triggeringSpell, uint8 effIndex=MAX_SPELL_EFFECTS) const
Definition SpellInfo.cpp:1033
uint32 CategoryRecoveryTime
Definition SpellInfo.h:350

References CustomSpellValues::AddSpellMod(), Unit::CastSpell(), SpellInfo::CategoryRecoveryTime, damage, effectHandleMode, SpellInfo::Effects, SpellInfo::GetCategory(), SpellInfo::GetExplicitTargetMask(), SpellInfo::Id, Object::IsPlayer(), LOG_DEBUG, m_caster, m_originalCasterGUID, m_spellInfo, m_targets, SpellInfo::NeedsToBeTriggeredByCaster(), Player::RemoveSpellCooldown(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_UNIT_MASK, Object::ToPlayer(), TRIGGERED_FULL_MASK, and unitTarget.

◆ EffectTriggerRitualOfSummoning()

void Spell::EffectTriggerRitualOfSummoning ( SpellEffIndex  effIndex)
1051{
1053 return;
1054
1055 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
1056 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
1057
1058 if (!spellInfo)
1059 {
1060 LOG_ERROR("spells.effect", "EffectTriggerRitualOfSummoning of spell {}: triggering unknown spell id {}", m_spellInfo->Id, triggered_spell_id);
1061 return;
1062 }
1063
1064 finish();
1065
1066 m_caster->CastSpell((Unit*)nullptr, spellInfo, true);
1067}

References Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, finish(), SpellInfo::Id, LOG_ERROR, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT, and sSpellMgr.

◆ EffectTriggerSpell()

void Spell::EffectTriggerSpell ( SpellEffIndex  effIndex)
Todo:
: move those to spell scripts
786{
789 return;
790
791 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
792
794 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_SPELL
796 {
797 // special cases
798 switch (triggered_spell_id)
799 {
800 // Mirror Image
801 case 58832:
802 {
803 // Glyph of Mirror Image
804 if (m_caster->HasAura(63093))
805 m_caster->CastSpell(m_caster, 65047, true); // Mirror Image
806
807 break;
808 }
809 // Demonic Empowerment -- succubus
810 case 54437:
811 {
815
816 // Cast Lesser Invisibility
817 unitTarget->CastSpell(unitTarget, 7870, true);
818 return;
819 }
820 // just skip
821 case 23770: // Sayge's Dark Fortune of *
822 // not exist, common cooldown can be implemented in scripts if need.
823 return;
824 // Brittle Armor - (need add max stack of 24575 Brittle Armor)
825 case 29284:
826 {
827 // Brittle Armor
828 SpellInfo const* spell = sSpellMgr->GetSpellInfo(24575);
829 if (!spell)
830 return;
831
832 for (uint32 j = 0; j < spell->StackAmount; ++j)
833 m_caster->CastSpell(unitTarget, spell->Id, true);
834 return;
835 }
836 // Mercurial Shield - (need add max stack of 26464 Mercurial Shield)
837 case 29286:
838 {
839 // Mercurial Shield
840 SpellInfo const* spell = sSpellMgr->GetSpellInfo(26464);
841 if (!spell)
842 return;
843
844 for (uint32 j = 0; j < spell->StackAmount; ++j)
845 m_caster->CastSpell(unitTarget, spell->Id, true);
846 return;
847 }
848 // Cloak of Shadows
849 case 35729:
850 {
853 for (Unit::AuraApplicationMap::iterator iter = Auras.begin(); iter != Auras.end();)
854 {
855 // remove all harmful spells on you...
856 SpellInfo const* spell = iter->second->GetBase()->GetSpellInfo();
857
858 // Pounce Bleed shouldn't be removed by Cloak of Shadows.
859 if (spell->GetAllEffectsMechanicMask() & 1 << MECHANIC_BLEED)
860 return;
861
862 bool dmgClassNone = false;
864 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
865 {
866 if ((iter->second->GetEffectMask() & (1 << i)) &&
867 spell->Effects[i].ApplyAuraName != SPELL_AURA_PERIODIC_DAMAGE &&
868 spell->Effects[i].ApplyAuraName != SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
869 spell->Effects[i].ApplyAuraName != SPELL_AURA_DUMMY)
870 {
871 dmgClassNone = false;
872 break;
873 }
874 dmgClassNone = true;
875 }
876
877 if ((spell->DmgClass == SPELL_DAMAGE_CLASS_MAGIC || (spell->GetDispelMask() & dispelMask) || dmgClassNone) &&
878 // ignore positive and passive auras
879 !iter->second->IsPositive() && !iter->second->GetBase()->IsPassive() &&
880 // Xinef: Ignore NPC spells having INVULNERABILITY attribute
882 {
883 m_caster->RemoveAura(iter);
884 }
885 else
886 ++iter;
887 }
888 return;
889 }
890 }
891 }
892
893 // normal case
894 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
895 if (!spellInfo)
896 {
897 LOG_DEBUG("spells.aura", "Spell::EffectTriggerSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
898 return;
899 }
900
901 SpellCastTargets targets;
903 {
904 if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex))
905 return;
906 targets.SetUnitTarget(unitTarget);
907 }
908 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH)
909 {
910 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
911 return;
912
914 targets.SetDst(m_targets);
915
916 if (Unit* target = m_targets.GetUnitTarget())
917 targets.SetUnitTarget(target);
918 else
919 targets.SetUnitTarget(m_caster);
920 }
921
922 CustomSpellValues values;
923 // set basepoints for trigger with value effect
925 {
926 // maybe need to set value only when basepoints == 0?
930 }
931
932 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
933 if (m_caster->IsPlayer() && spellInfo->CategoryRecoveryTime && m_spellInfo->GetCategory() == spellInfo->GetCategory())
934 {
935 m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
936 }
937
938 // original caster guid only for GO cast
940}
@ SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
Definition SharedDefines.h:931
@ SPELL_EFFECT_TRIGGER_SPELL
Definition SharedDefines.h:853
@ MECHANIC_BLEED
Definition SharedDefines.h:1351
@ DISPEL_ALL
Definition SharedDefines.h:1390
@ SPELL_AURA_MOD_STALKED
Definition SpellAuraDefines.h:131
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
Definition SpellAuraDefines.h:86

References CustomSpellValues::AddSpellMod(), Unit::CastSpell(), SpellInfo::CategoryRecoveryTime, damage, DISPEL_ALL, SpellInfo::DmgClass, EFFECT_0, effectHandleMode, SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Unit::GetAppliedAuras(), SpellInfo::GetCategory(), SpellInfo::GetDispelMask(), SpellInfo::GetExplicitTargetMask(), SpellCastTargets::GetUnitTarget(), SpellInfo::HasAttribute(), Unit::HasAura(), SpellInfo::Id, Object::IsPlayer(), LOG_DEBUG, m_caster, m_originalCasterGUID, m_spellInfo, m_targets, MAX_SPELL_EFFECTS, MECHANIC_BLEED, SpellInfo::NeedsToBeTriggeredByCaster(), Unit::RemoveAura(), Unit::RemoveAurasByType(), Unit::RemoveMovementImpairingAuras(), Player::RemoveSpellCooldown(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), SPELL_ATTR0_NO_IMMUNITIES, SPELL_AURA_DUMMY, SPELL_AURA_MOD_STALKED, SPELL_AURA_MOD_STUN, SPELL_AURA_PERIODIC_DAMAGE, SPELL_AURA_PERIODIC_TRIGGER_SPELL, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_NONE, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_EFFECT_TRIGGER_SPELL, SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE, SPELLFAMILY_GENERIC, SpellInfo::SpellFamilyName, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, SpellInfo::StackAmount, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_UNIT_MASK, Object::ToPlayer(), TRIGGERED_FULL_MASK, TRIGGERED_NO_PERIODIC_RESET, and unitTarget.

◆ EffectUnlearnSpecialization()

void Spell::EffectUnlearnSpecialization ( SpellEffIndex  effIndex)
1331{
1333 return;
1334
1335 if (!unitTarget)
1336 return;
1337
1338 Player* player = unitTarget->ToPlayer();
1339 if (!player)
1340 {
1341 return;
1342 }
1343
1344 uint32 spellToUnlearn = m_spellInfo->Effects[effIndex].TriggerSpell;
1345
1346 player->removeSpell(spellToUnlearn, SPEC_MASK_ALL, false);
1347 LOG_DEBUG("spells.aura", "Spell: Player {} has unlearned spell {} from Npc: {}",
1348 player->GetGUID().ToString(), spellToUnlearn, m_caster->GetGUID().ToString());
1349}
#define SPEC_MASK_ALL
Definition Player.h:177
void removeSpell(uint32 spellId, uint8 removeSpecMask, bool onlyTemporary)
Definition Player.cpp:3357

References effectHandleMode, SpellInfo::Effects, Object::GetGUID(), LOG_DEBUG, m_caster, m_spellInfo, Player::removeSpell(), SPEC_MASK_ALL, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectUntrainTalents()

void Spell::EffectUntrainTalents ( SpellEffIndex  effIndex)
2746{
2748 return;
2749
2750 if (!unitTarget || m_caster->IsPlayer())
2751 return;
2752
2753 if (ObjectGuid guid = m_caster->GetGUID()) // the trainer is the caster
2755}
void SendTalentWipeConfirm(ObjectGuid guid)
Definition Player.cpp:8966

References effectHandleMode, Object::GetGUID(), Object::IsPlayer(), m_caster, Player::SendTalentWipeConfirm(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectUnused()

void Spell::EffectUnused ( SpellEffIndex  effIndex)
244{
245 // NOT USED BY ANY SPELL OR USELESS OR IMPLEMENTED IN DIFFERENT WAY IN TRINITY
246}

◆ EffectWeaponDmg()

void Spell::EffectWeaponDmg ( SpellEffIndex  effIndex)
3318{
3320 return;
3321
3322 if (!unitTarget || !unitTarget->IsAlive())
3323 return;
3324
3325 // multiple weapon dmg effect workaround
3326 // execute only the last weapon damage
3327 // and handle all effects at once
3328 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
3329 {
3330 switch (m_spellInfo->Effects[j].Effect)
3331 {
3336 return; // we must calculate only at last weapon effect
3337 break;
3338 }
3339 }
3340
3341 // some spell specific modifiers
3342 float totalDamagePercentMod = 100.0f; // applied to final bonus+weapon damage
3343 int32 spell_bonus = 0; // bonus specific for spell
3344 bool normalized = false;
3345
3347 {
3349 {
3350 switch (m_spellInfo->Id)
3351 {
3352 // Trial of the Champion, Black Knight, Obliterate
3353 case 67725:
3354 case 67883:
3355 {
3356 AddPct(totalDamagePercentMod, unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), 1) * 30.0f);
3357 break;
3358 }
3359 }
3360 break;
3361 }
3363 {
3364 // Devastate (player ones)
3365 if (m_spellInfo->SpellFamilyFlags[1] & 0x40)
3366 {
3367 m_caster->CastSpell(unitTarget, 58567, true);
3368
3369 if (Aura* aur = unitTarget->GetAura(58567))
3370 {
3371 // 58388 - Glyph of Devastate dummy aura.
3372 if (m_caster->HasAura(58388))
3373 aur->ModStackAmount(1);
3374
3375 spell_bonus += (aur->GetStackAmount() - 1) * CalculateSpellDamage(2, unitTarget);
3376 }
3377 }
3378 break;
3379 }
3380 case SPELLFAMILY_ROGUE:
3381 {
3382 // Fan of Knives, Hemorrhage, Ghostly Strike
3383 if ((m_spellInfo->SpellFamilyFlags[1] & 0x40000)
3384 || (m_spellInfo->SpellFamilyFlags[0] & 0x6000000))
3385 {
3386 // Hemorrhage
3387 if (m_spellInfo->SpellFamilyFlags[0] & 0x2000000)
3388 {
3390 }
3391 // 50% more damage with daggers
3392 if (m_caster->IsPlayer())
3393 if (Item* item = m_caster->ToPlayer()->GetWeaponForAttack(m_attackType, true))
3394 if (item->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER)
3395 AddPct(totalDamagePercentMod, 50.0f);
3396 }
3397 // Mutilate (for each hand)
3398 else if (m_spellInfo->SpellFamilyFlags[1] & 0x6)
3399 {
3400 bool found = false;
3401 // fast check
3403 found = true;
3404 // full aura scan
3405 else
3406 {
3408 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
3409 {
3410 if (itr->second->GetBase()->GetSpellInfo()->Dispel == DISPEL_POISON)
3411 {
3412 found = true;
3413 break;
3414 }
3415 }
3416 }
3417
3418 if (found)
3419 AddPct(totalDamagePercentMod, 20.0f); // 120% if poisoned
3420 }
3421 break;
3422 }
3424 {
3425 switch (m_spellInfo->Id)
3426 {
3427 case 20467: // Seal of Command Unleashed
3428 spell_bonus += int32(0.08f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
3430 break;
3431 case 53385: // Divine Storm deals normalized damage
3432 normalized = true;
3433 break;
3434 default:
3435 break;
3436 }
3437 break;
3438 }
3439 case SPELLFAMILY_SHAMAN:
3440 {
3441 // Skyshatter Harness item set bonus
3442 // Stormstrike
3443 if (AuraEffect* aurEff = m_caster->IsScriptOverriden(m_spellInfo, 5634))
3444 m_caster->CastSpell(m_caster, 38430, true, nullptr, aurEff);
3445 // Lava lash damage increased by Flametongue weapon
3447 AddPct(totalDamagePercentMod, 25.0f);
3448 break;
3449 }
3450 case SPELLFAMILY_DRUID:
3451 {
3452 // Mangle (Cat): CP
3453 if (m_spellInfo->SpellFamilyFlags[1] & 0x400)
3454 {
3456 }
3457 // Shred, Maul - Rend and Tear
3459 {
3460 if (AuraEffect const* rendAndTear = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 2859, 0))
3461 AddPct(totalDamagePercentMod, rendAndTear->GetAmount());
3462 }
3463 break;
3464 }
3465 case SPELLFAMILY_HUNTER:
3466 {
3467 // Kill Shot
3468 if (m_spellInfo->SpellFamilyFlags[1] & 0x800000)
3469 {
3470 spell_bonus += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.4f);
3471 }
3472 break;
3473 }
3475 {
3476 // Plague Strike
3477 if (m_spellInfo->SpellFamilyFlags[0] & 0x1)
3478 {
3479 // Glyph of Plague Strike
3480 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(58657, EFFECT_0))
3481 AddPct(totalDamagePercentMod, aurEff->GetAmount());
3482 break;
3483 }
3484 // Blood Strike
3485 if (m_spellInfo->SpellFamilyFlags[0] & 0x400000)
3486 {
3487 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3488 //Death Knight T8 Melee 4P Bonus
3489 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736))
3490 AddPct(disease_amt, aurEff->GetAmount());
3491
3492 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) / 2.0f);
3493
3494 // Glyph of Blood Strike
3495 if (m_caster->GetAuraEffect(59332, EFFECT_0))
3497 AddPct(totalDamagePercentMod, 20.0f);
3498 break;
3499 }
3500 // Death Strike
3501 if (m_spellInfo->SpellFamilyFlags[0] & 0x10)
3502 {
3503 // Glyph of Death Strike
3504 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(59336, EFFECT_0))
3505 if (uint32 runic = std::min<uint32>(m_caster->GetPower(POWER_RUNIC_POWER), aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()))
3506 AddPct(totalDamagePercentMod, runic);
3507 break;
3508 }
3509 // Obliterate (12.5% more damage per disease)
3510 if (m_spellInfo->SpellFamilyFlags[1] & 0x20000)
3511 {
3512 bool consumeDiseases = true;
3513 // Annihilation
3515 // Do not consume diseases if roll sucesses
3516 if (roll_chance_i(aurEff->GetAmount()))
3517 consumeDiseases = false;
3518
3519 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3520 //Death Knight T8 Melee 4P Bonus
3521 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736))
3522 AddPct(disease_amt, aurEff->GetAmount());
3523
3524 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), consumeDiseases) / 2.0f);
3525 break;
3526 }
3527 // Blood-Caked Strike - Blood-Caked Blade
3528 if (m_spellInfo->SpellIconID == 1736)
3529 {
3530 AddPct(totalDamagePercentMod, unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) * 50.0f);
3531 break;
3532 }
3533 // Heart Strike
3534 if (m_spellInfo->SpellFamilyFlags[0] & 0x1000000)
3535 {
3536 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3537 //Death Knight T8 Melee 4P Bonus
3538 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736))
3539 AddPct(disease_amt, aurEff->GetAmount());
3540
3541 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()));
3542 break;
3543 }
3544 // Rune Strike
3545 if (m_spellInfo->SpellFamilyFlags[1] & 0x20000000)
3546 {
3547 spell_bonus += int32(0.15f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
3548 }
3549
3550 break;
3551 }
3552 }
3553
3554 float weaponDamagePercentMod = 100.0f;
3555 int32 fixed_bonus = 0;
3556
3557 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
3558 {
3559 switch (m_spellInfo->Effects[j].Effect)
3560 {
3563 fixed_bonus += CalculateSpellDamage(j, unitTarget);
3564 break;
3566 fixed_bonus += CalculateSpellDamage(j, unitTarget);
3567 normalized = true;
3568 break;
3570 ApplyPct(weaponDamagePercentMod, CalculateSpellDamage(j, unitTarget));
3571 break;
3572 default:
3573 break; // not weapon damage effect, just skip
3574 }
3575 }
3576
3577 bool const isPhysical = (m_spellSchoolMask & SPELL_SCHOOL_MASK_NORMAL);
3578 if (isPhysical && (fixed_bonus || spell_bonus))
3579 {
3580 UnitMods unitMod;
3581 switch (m_attackType)
3582 {
3583 default:
3584 case BASE_ATTACK:
3585 unitMod = UNIT_MOD_DAMAGE_MAINHAND;
3586 break;
3587 case OFF_ATTACK:
3588 unitMod = UNIT_MOD_DAMAGE_OFFHAND;
3589 break;
3590 case RANGED_ATTACK:
3591 unitMod = UNIT_MOD_DAMAGE_RANGED;
3592 break;
3593 }
3594 float weapon_total_pct = m_caster->GetModifierValue(unitMod, TOTAL_PCT);
3595 fixed_bonus = int32(fixed_bonus * weapon_total_pct);
3596 spell_bonus = int32(spell_bonus * weapon_total_pct);
3597 }
3598
3599 int32 weaponDamage = 0;
3600 // Dancing Rune Weapon
3601 if (m_caster->GetEntry() == 27893)
3602 {
3603 if (Unit* owner = m_caster->GetOwner())
3604 weaponDamage = owner->CalculateDamage(m_attackType, normalized, isPhysical);
3605 }
3606 else
3607 {
3608 weaponDamage = m_caster->CalculateDamage(m_attackType, normalized, isPhysical);
3609 }
3610
3611 // Sequence is important
3612 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
3613 {
3614 // We assume that a spell have at most one fixed_bonus
3615 // and at most one weaponDamagePercentMod
3616 switch (m_spellInfo->Effects[j].Effect)
3617 {
3621 weaponDamage += fixed_bonus;
3622 break;
3624 ApplyPct(weaponDamage, weaponDamagePercentMod);
3625 default:
3626 break; // not weapon damage effect, just skip
3627 }
3628 }
3629
3630 weaponDamage += spell_bonus;
3631 ApplyPct(weaponDamage, totalDamagePercentMod);
3632
3633 // prevent negative damage
3634 uint32 eff_damage(std::max(weaponDamage, 0));
3635
3636 // Add melee damage bonuses (also check for negative)
3639
3640 // Meteor like spells (divided damage to targets)
3642 {
3643 uint32 count = 0;
3644 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3645 if (ihit->effectMask & (1 << effIndex))
3646 ++count;
3647
3648 eff_damage /= count; // divide to all targets
3649 }
3650
3651 m_damage += eff_damage;
3652}
@ ITEM_SUBCLASS_WEAPON_DAGGER
Definition ItemTemplate.h:359
@ POWER_RUNIC_POWER
Definition SharedDefines.h:286
@ SPELL_EFFECT_NORMALIZED_WEAPON_DMG
Definition SharedDefines.h:910
@ SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
Definition SharedDefines.h:820
@ AURA_STATE_DEADLY_POISON
Definition SharedDefines.h:1319
@ AURA_STATE_BLEEDING
Definition SharedDefines.h:1321
@ DISPEL_POISON
Definition SharedDefines.h:1387
UnitMods
Definition Unit.h:143
@ UNIT_MOD_DAMAGE_OFFHAND
Definition Unit.h:167
@ UNIT_MOD_DAMAGE_RANGED
Definition Unit.h:168
@ UNIT_MOD_DAMAGE_MAINHAND
Definition Unit.h:166
@ TOTAL_PCT
Definition Unit.h:130
uint32 MeleeDamageBonusTaken(Unit *attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition Unit.cpp:13370
uint32 GetDiseasesByCaster(ObjectGuid casterGUID, uint8 mode=0)
Definition Unit.cpp:5909
bool HasDecreaseSpeedAura() const
Definition Unit.h:1743
AuraEffect * GetAuraEffectDummy(uint32 spellid) const
Definition Unit.cpp:5615
float GetModifierValue(UnitMods unitMod, UnitModifierType modifierType) const
Definition Unit.cpp:15389
uint32 CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, uint8 itemDamagesMask=0)
Definition Unit.cpp:3018
int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask)
Definition Unit.cpp:12029
uint32 MeleeDamageBonusDone(Unit *pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition Unit.cpp:13168

References AddComboPointGain(), AddPct(), ApplyPct(), AURA_STATE_BLEEDING, AURA_STATE_DEADLY_POISON, BASE_ATTACK, Unit::CalculateDamage(), CalculateSpellDamage(), Unit::CastSpell(), DISPEL_POISON, EFFECT_0, EFFECT_1, EFFECT_2, effectHandleMode, SpellInfo::Effects, Unit::GetAppliedAuras(), Unit::GetAura(), Unit::GetAuraEffect(), Unit::GetAuraEffectDummy(), Unit::GetDiseasesByCaster(), Unit::GetDummyAuraEffect(), Object::GetEntry(), Object::GetGUID(), Unit::GetModifierValue(), Unit::GetOwner(), Unit::GetPower(), SpellInfo::GetSchoolMask(), Unit::GetTotalAttackPowerValue(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), Unit::HasAura(), Unit::HasAuraState(), Unit::HasDecreaseSpeedAura(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), Unit::IsScriptOverriden(), ITEM_SUBCLASS_WEAPON_DAGGER, m_attackType, m_caster, m_damage, m_spellInfo, m_spellSchoolMask, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, Unit::MeleeDamageBonusDone(), Unit::MeleeDamageBonusTaken(), OFF_ATTACK, POWER_RUNIC_POWER, RANGED_ATTACK, roll_chance_i(), SPELL_ATTR0_CU_SHARE_DAMAGE, SPELL_AURA_DUMMY, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_EFFECT_NORMALIZED_WEAPON_DMG, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, Unit::SpellBaseDamageBonusDone(), SPELLFAMILY_DEATHKNIGHT, SPELLFAMILY_DRUID, SPELLFAMILY_GENERIC, SPELLFAMILY_HUNTER, SPELLFAMILY_PALADIN, SPELLFAMILY_ROGUE, SPELLFAMILY_SHAMAN, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellIconID, Object::ToPlayer(), TOTAL_PCT, UNIT_MOD_DAMAGE_MAINHAND, UNIT_MOD_DAMAGE_OFFHAND, UNIT_MOD_DAMAGE_RANGED, and unitTarget.

◆ ExecuteLogEffectCreateItem()

void Spell::ExecuteLogEffectCreateItem ( uint8  effIndex,
uint32  entry 
)
5174{
5175 InitEffectExecuteData(effIndex);
5176 *m_effectExecuteData[effIndex] << uint32(entry);
5177}
void InitEffectExecuteData(uint8 effIndex)
Definition Spell.cpp:8528

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectCreateItem().

◆ ExecuteLogEffectDestroyItem()

void Spell::ExecuteLogEffectDestroyItem ( uint8  effIndex,
uint32  entry 
)
5180{
5181 InitEffectExecuteData(effIndex);
5182 *m_effectExecuteData[effIndex] << uint32(entry);
5183}

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectFeedPet().

◆ ExecuteLogEffectDurabilityDamage()

void Spell::ExecuteLogEffectDurabilityDamage ( uint8  effIndex,
Unit victim,
int32  itemId,
int32  slot 
)
5160{
5161 InitEffectExecuteData(effIndex);
5162 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5163 *m_effectExecuteData[effIndex] << int32(itemId);
5164 *m_effectExecuteData[effIndex] << int32(slot);
5165}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectDurabilityDamage().

◆ ExecuteLogEffectExtraAttacks()

void Spell::ExecuteLogEffectExtraAttacks ( uint8  effIndex,
Unit victim,
uint32  attCount 
)
5146{
5147 InitEffectExecuteData(effIndex);
5148 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5149 *m_effectExecuteData[effIndex] << uint32(attCount);
5150}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectAddExtraAttacks().

◆ ExecuteLogEffectInterruptCast()

void Spell::ExecuteLogEffectInterruptCast ( uint8  effIndex,
Unit victim,
uint32  spellId 
)
5153{
5154 InitEffectExecuteData(effIndex);
5155 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5156 *m_effectExecuteData[effIndex] << uint32(spellId);
5157}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectInterruptCast().

◆ ExecuteLogEffectOpenLock()

void Spell::ExecuteLogEffectOpenLock ( uint8  effIndex,
Object obj 
)
5168{
5169 InitEffectExecuteData(effIndex);
5170 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5171}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectOpenLock().

◆ ExecuteLogEffectResurrect()

void Spell::ExecuteLogEffectResurrect ( uint8  effIndex,
Unit target 
)
5198{
5199 InitEffectExecuteData(effIndex);
5200 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5201}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectResurrect(), and EffectResurrectNew().

◆ ExecuteLogEffectSummonObject()

◆ ExecuteLogEffectTakeTargetPower()

void Spell::ExecuteLogEffectTakeTargetPower ( uint8  effIndex,
Unit target,
uint32  PowerType,
uint32  powerTaken,
float  gainMultiplier 
)
5137{
5138 InitEffectExecuteData(effIndex);
5139 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5140 *m_effectExecuteData[effIndex] << uint32(powerTaken);
5141 *m_effectExecuteData[effIndex] << uint32(PowerType);
5142 *m_effectExecuteData[effIndex] << float(gainMultiplier);
5143}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectPowerBurn(), EffectPowerDrain(), and spell_mage_burnout_trigger::HandleDummy().

◆ ExecuteLogEffectUnsummonObject()

void Spell::ExecuteLogEffectUnsummonObject ( uint8  effIndex,
WorldObject obj 
)
5192{
5193 InitEffectExecuteData(effIndex);
5194 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5195}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectDismissPet().

◆ finish()

void Spell::finish ( bool  ok = true)
4507{
4508 if (!m_caster)
4509 return;
4510
4512 return;
4514
4515 if (m_spellInfo->IsChanneled())
4517
4520
4521 // Unsummon summon as possessed creatures on spell cancel
4523 {
4524 if (Unit* charm = m_caster->GetCharm())
4525 if (charm->IsCreature()
4526 && charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_PUPPET)
4527 && charm->GetUInt32Value(UNIT_CREATED_BY_SPELL) == m_spellInfo->Id)
4528 ((Puppet*)charm)->UnSummon();
4529 }
4530
4531 if (Creature* creatureCaster = m_caster->ToCreature())
4532 creatureCaster->ReleaseFocus(this);
4533
4534 if (ok)
4535 {
4538 }
4539 else
4540 {
4541 if (m_caster->IsPlayer())
4542 {
4543 // Xinef: Restore spell mods in case of fail cast
4545
4546 // Xinef: Reset cooldown event in case of fail cast
4549
4550 // Rogue fix: Remove Cold Blood if Mutilate off-hand failed
4551 if (m_spellInfo->Id == 27576) // Mutilate, off-hand
4552 if (m_caster->HasAura(14177))
4553 m_caster->RemoveAura(14177);
4554 }
4555 return;
4556 }
4557
4558 // pussywizard:
4561
4563 {
4564 // Unsummon statue
4566 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell);
4567 if (spellInfo && spellInfo->SpellIconID == 2056)
4568 {
4569 LOG_DEBUG("spells.aura", "Statue {} is unsummoned in spell {} finish", m_caster->GetGUID().ToString(), m_spellInfo->Id);
4571 return;
4572 }
4573 }
4574
4575 // potions disabled by client, send event "not in combat" if need
4578
4579 // Take mods after trigger spell (needed for 14177 to affect 48664)
4580 // mods are taken only on succesfull cast and independantly from targets of the spell
4581 if (Player* player = m_caster->GetSpellModOwner())
4582 player->RemoveSpellMods(this);
4583
4584 // xinef: clear reactive auras states after spell cast
4587
4588 // Stop Attack for some spells
4591}
@ ENCOUNTER_CREDIT_CAST_SPELL
Definition Map.h:156
@ AURA_STATE_DEFENSE
Definition SharedDefines.h:1303
@ AURA_STATE_HUNTER_PARRY
Definition SharedDefines.h:1309
@ SPELL_ATTR0_CU_ENCOUNTER_REWARD
Definition SpellInfo.h:208
@ UNIT_MASK_PUPPET
Definition UnitDefines.h:162
void UpdateEncounterState(EncounterCreditType type, uint32 creditEntry, Unit *source)
Definition Map.cpp:2521
void UpdatePotionCooldown(Spell *spell=nullptr)
Definition PlayerUpdates.cpp:1547
Definition TemporarySummon.h:115
virtual void setDeathState(DeathState s, bool despawn=false)
Definition Unit.cpp:14654
void UpdateInterruptMask()
Definition Unit.cpp:769
void ModifyAuraState(AuraStateType flag, bool apply)
Definition Unit.cpp:10592

References Unit::AttackStop(), AURA_STATE_DEFENSE, AURA_STATE_HUNTER_PARRY, SpellInfo::CasterAuraState, Unit::ClearUnitState(), ENCOUNTER_CREDIT_CAST_SPELL, WorldObject::FindMap(), Unit::GetCharm(), Object::GetGUID(), Unit::GetSpellModOwner(), Object::GetUInt32Value(), SpellInfo::HasAttribute(), Unit::HasAura(), Unit::HasUnitState(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsCooldownStartedOnEvent(), Object::IsCreature(), Unit::IsNonMeleeSpellCast(), Object::IsPlayer(), Unit::IsSummon(), JustDied, LOG_DEBUG, m_caster, m_spellInfo, m_spellState, m_triggeredByAuraSpell, Unit::ModifyAuraState(), Unit::RemoveAura(), Player::RemoveSpellCooldown(), Player::RestoreSpellMods(), Player::SendCooldownEvent(), Unit::setDeathState(), SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_ATTR0_CU_ENCOUNTER_REWARD, SPELL_STATE_FINISHED, SpellInfo::SpellIconID, sSpellMgr, Object::ToCreature(), Object::ToPlayer(), ObjectGuid::ToString(), UNIT_CREATED_BY_SPELL, UNIT_MASK_PUPPET, UNIT_STATE_CASTING, Map::UpdateEncounterState(), Unit::UpdateInterruptMask(), and Player::UpdatePotionCooldown().

Referenced by _cast(), Unit::AttackerStateUpdate(), cancel(), EffectInstaKill(), EffectTameCreature(), EffectTriggerRitualOfSummoning(), SpellScript::FinishCast(), Unit::FinishSpell(), handle_delayed(), handle_immediate(), WorldSession::HandleCastSpellOpcode(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), prepare(), SelectImplicitCasterDestTargets(), SelectSpellTargets(), and update().

◆ FinishTargetProcessing()

void Spell::FinishTargetProcessing ( )
protected
8524{
8526}
void SendLogExecute()
Definition Spell.cpp:5102

References SendLogExecute().

Referenced by handle_delayed(), handle_immediate(), and HandleLaunchPhase().

◆ GetCaster()

Unit * Spell::GetCaster ( ) const
inline

◆ GetCastTime()

◆ GetCastTimeRemaining()

int32 Spell::GetCastTimeRemaining ( )
inline
574{ return m_timer;}

References m_timer.

◆ GetCurrentContainer()

CurrentSpellTypes Spell::GetCurrentContainer ( ) const

◆ GetDebugInfo()

std::string Spell::GetDebugInfo ( ) const
protected
8987{
8988 std::stringstream sstr;
8989 sstr << std::boolalpha
8990 << "Id: " << GetSpellInfo()->Id << " OriginalCaster: " << m_originalCasterGUID.ToString()
8991 << " State: " << getState();
8992 return sstr.str();
8993}

References GetSpellInfo(), getState(), SpellInfo::Id, m_originalCasterGUID, and ObjectGuid::ToString().

◆ GetDelayMoment()

uint64 Spell::GetDelayMoment ( ) const
inline

◆ GetDelayStart()

uint64 Spell::GetDelayStart ( ) const
inline
586{ return m_delayStart; }

References m_delayStart.

Referenced by SpellEvent::Execute(), and RecalculateDelayMomentForDst().

◆ GetDelayTrajectory()

uint64 Spell::GetDelayTrajectory ( ) const
inline
589{ return m_delayTrajectory; }

References m_delayTrajectory.

◆ GetOriginalCaster()

Unit * Spell::GetOriginalCaster ( ) const
inline

◆ GetPowerCost()

int32 Spell::GetPowerCost ( ) const
inline
600{ return m_powerCost; }

References m_powerCost.

Referenced by Unit::HandleDummyAuraProc().

◆ GetSearcherTypeMask()

uint32 Spell::GetSearcherTypeMask ( SpellTargetObjectTypes  objType,
std::shared_ptr< ConditionList condList 
)
2123{
2124 // this function selects which containers need to be searched for spell target
2126
2127 // filter searchers based on searched object type
2128 switch (objType)
2129 {
2136 break;
2140 break;
2141 default:
2142 break;
2143 }
2145 retMask &= ~GRID_MAP_TYPE_MASK_CORPSE;
2149 retMask &= GRID_MAP_TYPE_MASK_PLAYER;
2151 retMask &= ~GRID_MAP_TYPE_MASK_PLAYER;
2152
2153 if (condList)
2154 retMask &= sConditionMgr->GetSearcherTypeMaskForConditionList(*condList);
2155 return retMask;
2156}
@ GRID_MAP_TYPE_MASK_PLAYER
Definition GridDefines.h:75
@ GRID_MAP_TYPE_MASK_CREATURE
Definition GridDefines.h:72
@ GRID_MAP_TYPE_MASK_ALL
Definition GridDefines.h:76
@ GRID_MAP_TYPE_MASK_GAMEOBJECT
Definition GridDefines.h:74
@ GRID_MAP_TYPE_MASK_CORPSE
Definition GridDefines.h:71
@ SPELL_ATTR5_NOT_ON_PLAYER
Definition SharedDefines.h:585
@ SPELL_ATTR2_ALLOW_DEAD_TARGET
Definition SharedDefines.h:467
@ SPELL_ATTR3_ONLY_ON_GHOSTS
Definition SharedDefines.h:516
@ SPELL_ATTR3_ONLY_ON_PLAYER
Definition SharedDefines.h:512
@ TARGET_OBJECT_TYPE_CORPSE
Definition SpellInfo.h:107
@ TARGET_OBJECT_TYPE_GOBJ
Definition SpellInfo.h:104
@ TARGET_OBJECT_TYPE_CORPSE_ALLY
Definition SpellInfo.h:110
@ TARGET_OBJECT_TYPE_CORPSE_ENEMY
Definition SpellInfo.h:109
@ TARGET_OBJECT_TYPE_GOBJ_ITEM
Definition SpellInfo.h:105

References GRID_MAP_TYPE_MASK_ALL, GRID_MAP_TYPE_MASK_CORPSE, GRID_MAP_TYPE_MASK_CREATURE, GRID_MAP_TYPE_MASK_GAMEOBJECT, GRID_MAP_TYPE_MASK_PLAYER, SpellInfo::HasAttribute(), m_spellInfo, sConditionMgr, SPELL_ATTR2_ALLOW_DEAD_TARGET, SPELL_ATTR3_ONLY_ON_GHOSTS, SPELL_ATTR3_ONLY_ON_PLAYER, SPELL_ATTR5_NOT_ON_PLAYER, TARGET_OBJECT_TYPE_CORPSE, TARGET_OBJECT_TYPE_CORPSE_ALLY, TARGET_OBJECT_TYPE_CORPSE_ENEMY, TARGET_OBJECT_TYPE_GOBJ, TARGET_OBJECT_TYPE_GOBJ_ITEM, TARGET_OBJECT_TYPE_UNIT, and TARGET_OBJECT_TYPE_UNIT_AND_DEST.

Referenced by SearchAreaTargets(), SearchNearbyTarget(), and SelectImplicitConeTargets().

◆ GetSpellInfo()

◆ GetSpellSchoolMask()

SpellSchoolMask Spell::GetSpellSchoolMask ( ) const
inline

◆ GetSpellValue()

SpellValue const * Spell::GetSpellValue ( )
inline
607{ return m_spellValue; }

References m_spellValue.

Referenced by DoAllEffectOnTarget().

◆ getState()

◆ GetTriggeredByAuraTickNumber()

uint32 Spell::GetTriggeredByAuraTickNumber ( ) const
inline

◆ GetTriggeredCastFlags()

TriggerCastFlags Spell::GetTriggeredCastFlags ( ) const
inline
615{ return _triggeredCastFlags; }

References _triggeredCastFlags.

◆ GetUniqueTargetInfo()

◆ handle_delayed()

uint64 Spell::handle_delayed ( uint64  t_offset)
4195{
4196 if (!UpdatePointers())
4197 {
4198 // finish the spell if UpdatePointers() returned false, something wrong happened there
4199 finish(false);
4200 return 0;
4201 }
4202
4203 Player* modOwner = m_caster->GetSpellModOwner();
4204 if (modOwner)
4205 modOwner->SetSpellModTakingSpell(this, true);
4206
4207 uint64 next_time = m_delayTrajectory;
4208
4210
4211 if (!m_immediateHandled && m_delayTrajectory <= t_offset)
4212 {
4214 m_immediateHandled = true;
4216 next_time = 0;
4217 }
4218
4219 bool single_missile = (m_targets.HasDst());
4220
4221 // now recheck units targeting correctness (need before any effects apply to prevent adding immunity at first effect not allow apply second spell effect and similar cases)
4222 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4223 {
4224 if (ihit->processed == false)
4225 {
4226 if (single_missile || ihit->timeDelay <= t_offset)
4227 {
4228 ihit->timeDelay = t_offset;
4229 DoAllEffectOnTarget(&(*ihit));
4230 }
4231 else if (next_time == 0 || ihit->timeDelay < next_time)
4232 next_time = ihit->timeDelay;
4233 }
4234 }
4235
4236 // now recheck gameobject targeting correctness
4237 for (std::list<GOTargetInfo>::iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end(); ++ighit)
4238 {
4239 if (ighit->processed == false)
4240 {
4241 if (single_missile || ighit->timeDelay <= t_offset)
4242 DoAllEffectOnTarget(&(*ighit));
4243 else if (next_time == 0 || ighit->timeDelay < next_time)
4244 next_time = ighit->timeDelay;
4245 }
4246 }
4247
4249
4250 if (modOwner)
4251 modOwner->SetSpellModTakingSpell(this, false);
4252
4253 // All targets passed - need finish phase
4254 if (next_time == 0)
4255 {
4256 // spell is finished, perform some last features of the spell here
4258
4259 finish(true); // successfully finish spell cast
4260
4261 // return zero, spell is finished now
4262 return 0;
4263 }
4264 else
4265 {
4266 // spell is unfinished, return next execution time
4267 return next_time;
4268 }
4269}
void _handle_finish_phase()
Definition Spell.cpp:4299
void PrepareTargetProcessing()
Definition Spell.cpp:8518
void _handle_immediate_phase()
Definition Spell.cpp:4271
void FinishTargetProcessing()
Definition Spell.cpp:8523

References _handle_finish_phase(), _handle_immediate_phase(), DoAllEffectOnTarget(), finish(), FinishTargetProcessing(), Unit::GetSpellModOwner(), SpellCastTargets::HasDst(), m_caster, m_delayTrajectory, m_immediateHandled, m_targets, m_UniqueGOTargetInfo, m_UniqueTargetInfo, PrepareTargetProcessing(), Player::SetSpellModTakingSpell(), and UpdatePointers().

Referenced by SpellEvent::Execute().

◆ handle_immediate()

void Spell::handle_immediate ( )
4135{
4136 // start channeling if applicable
4137 if (m_spellInfo->IsChanneled())
4138 {
4139 int32 duration = m_spellInfo->GetDuration();
4141 duration = -1;
4142
4143 if (duration > 0)
4144 {
4145 // First mod_duration then haste - see Missile Barrage
4146 // Apply duration mod
4147 if (Player* modOwner = m_caster->GetSpellModOwner())
4148 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
4149
4150 // Apply haste mods
4152 duration = int32(duration * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
4153
4156 m_channeledDuration = duration;
4157 SendChannelStart(duration);
4158 }
4159 else if (duration == -1)
4160 {
4163 SendChannelStart(duration);
4164 }
4165 }
4166
4168
4169 // process immediate effects (items, ground, etc.) also initialize some variables
4171
4172 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4173 DoAllEffectOnTarget(&(*ihit));
4174
4175 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
4176 DoAllEffectOnTarget(&(*ihit));
4177
4179
4180 // spell is finished, perform some last features of the spell here
4182
4183 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4184 TakeCastItem();
4185
4186 // handle ammo consumption for Hunter's volley spell
4188 TakeAmmo();
4189
4191 finish(true); // successfully finish spell cast (not last in case autorepeat or channel spell)
4192}
void SendChannelStart(uint32 duration)
Definition Spell.cpp:5235
void TakeAmmo()
Definition Spell.cpp:5408
void AddInterruptMask(uint32 mask)
Definition Unit.h:1525

References _handle_finish_phase(), _handle_immediate_phase(), Unit::AddInterruptMask(), SpellInfo::ChannelInterruptFlags, DoAllEffectOnTarget(), finish(), FinishTargetProcessing(), SpellInfo::GetDuration(), Object::GetFloatValue(), Unit::GetSpellModOwner(), SpellInfo::HasAttribute(), Unit::HasAuraTypeWithAffectMask(), HasTriggeredCastFlag(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsRangedWeaponSpell(), m_caster, m_channeledDuration, m_spellInfo, m_spellState, m_UniqueGOTargetInfo, m_UniqueTargetInfo, PrepareTargetProcessing(), SendChannelStart(), SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC, SPELL_AURA_PERIODIC_HASTE, SPELL_STATE_CASTING, SPELLMOD_DURATION, TakeAmmo(), TakeCastItem(), TRIGGERED_IGNORE_EFFECTS, and UNIT_MOD_CAST_SPEED.

Referenced by _cast().

◆ HandleEffects()

void Spell::HandleEffects ( Unit pUnitTarget,
Item pItemTarget,
GameObject pGOTarget,
uint32  i,
SpellEffectHandleMode  mode 
)
5658{
5660 return;
5661
5662 effectHandleMode = mode;
5663 unitTarget = pUnitTarget;
5664 itemTarget = pItemTarget;
5665 gameObjTarget = pGOTarget;
5667
5668 uint8 eff = m_spellInfo->Effects[i].Effect;
5669
5670 LOG_DEBUG("spells.aura", "Spell: {} Effect : {}", m_spellInfo->Id, eff);
5671
5672 // we do not need DamageMultiplier here.
5673 damage = CalculateSpellDamage(i, nullptr);
5674
5675 bool preventDefault = CallScriptEffectHandlers((SpellEffIndex)i, mode);
5676
5677 if (!preventDefault && eff < TOTAL_SPELL_EFFECTS)
5678 {
5679 (this->*SpellEffects[eff])((SpellEffIndex)i);
5680 }
5681}
SpellEffIndex
Definition SharedDefines.h:30
SpellEffects
Definition SharedDefines.h:789
@ TOTAL_SPELL_EFFECTS
Definition SharedDefines.h:954
bool CallScriptEffectHandlers(SpellEffIndex effIndex, SpellEffectHandleMode mode)
Definition Spell.cpp:8637
WorldLocation _position
Definition Spell.h:112

References SpellDestination::_position, CalculateSpellDamage(), CallScriptEffectHandlers(), damage, destTarget, effectHandleMode, SpellInfo::Effects, gameObjTarget, HasTriggeredCastFlag(), SpellInfo::Id, itemTarget, LOG_DEBUG, m_destTargets, m_spellInfo, TOTAL_SPELL_EFFECTS, TRIGGERED_IGNORE_EFFECTS, and unitTarget.

Referenced by _handle_immediate_phase(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoAllEffectOnTarget(), DoAllEffectOnTarget(), DoSpellHitOnUnit(), and HandleLaunchPhase().

◆ HandleLaunchPhase()

void Spell::HandleLaunchPhase ( )
protected
8277{
8278 // handle effects with SPELL_EFFECT_HANDLE_LAUNCH mode
8279 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8280 {
8281 // don't do anything for empty effect
8282 if (!m_spellInfo->Effects[i].IsEffect())
8283 continue;
8284
8285 HandleEffects(nullptr, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH);
8286 }
8287
8288 float multiplier[MAX_SPELL_EFFECTS];
8289 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8290 if (m_applyMultiplierMask & (1 << i))
8291 multiplier[i] = m_spellInfo->Effects[i].CalcDamageMultiplier(m_originalCaster, this);
8292
8295 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
8296 {
8297 if ((*j)->IsAffectedOnSpell(m_spellInfo))
8298 usesAmmo = false;
8299 }
8300
8302
8303 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
8304 {
8305 TargetInfo& target = *ihit;
8306
8307 uint32 mask = target.effectMask;
8308 if (!mask)
8309 continue;
8310
8311 // do not consume ammo anymore for Hunter's volley spell
8313 usesAmmo = false;
8314
8315 if (usesAmmo)
8316 {
8317 bool ammoTaken = false;
8318 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
8319 {
8320 if (!(mask & 1 << i))
8321 continue;
8322 switch (m_spellInfo->Effects[i].Effect)
8323 {
8329 ammoTaken = true;
8330 TakeAmmo();
8331 }
8332 if (ammoTaken)
8333 break;
8334 }
8335 }
8336
8337 DoAllEffectOnLaunchTarget(target, multiplier);
8338 }
8339
8341}
@ SPELL_EFFECT_SCHOOL_DAMAGE
Definition SharedDefines.h:791
@ SPELL_AURA_ABILITY_CONSUME_NO_AMMO
Definition SpellAuraDefines.h:337
@ SPELL_ATTR0_CU_DIRECT_DAMAGE
Definition SpellInfo.h:185
void DoAllEffectOnLaunchTarget(TargetInfo &targetInfo, float *multiplier)
Definition Spell.cpp:8343

References DoAllEffectOnLaunchTarget(), TargetInfo::effectMask, SpellInfo::Effects, FinishTargetProcessing(), Unit::GetAuraEffectsByType(), HandleEffects(), SpellInfo::HasAttribute(), SpellInfo::IsTargetingArea(), IsTriggered(), m_applyMultiplierMask, m_caster, m_originalCaster, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, PrepareTargetProcessing(), SPELL_ATTR0_CU_DIRECT_DAMAGE, SPELL_AURA_ABILITY_CONSUME_NO_AMMO, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_NORMALIZED_WEAPON_DMG, SPELL_EFFECT_SCHOOL_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE, SPELLFAMILY_HUNTER, SpellInfo::SpellFamilyName, and TakeAmmo().

Referenced by _cast().

◆ HandleThreatSpells()

void Spell::HandleThreatSpells ( )
5611{
5612 if (m_UniqueTargetInfo.empty())
5613 return;
5614
5616 return;
5617
5618 float threat = 0.0f;
5619 if (SpellThreatEntry const* threatEntry = sSpellMgr->GetSpellThreatEntry(m_spellInfo->Id))
5620 {
5621 if (threatEntry->apPctMod != 0.0f)
5622 threat += threatEntry->apPctMod * m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
5623
5624 threat += threatEntry->flatMod;
5625 }
5627 threat += m_spellInfo->SpellLevel;
5628
5629 // past this point only multiplicative effects occur
5630 if (threat == 0.0f)
5631 return;
5632
5633 // since 2.0.1 threat from positive effects also is distributed among all targets, so the overall caused threat is at most the defined bonus
5634 threat /= m_UniqueTargetInfo.size();
5635
5636 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5637 {
5638 float threatToAdd = threat;
5639 if (ihit->missCondition != SPELL_MISS_NONE)
5640 threatToAdd = 0.0f;
5641
5642 Unit* target = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
5643 if (!target)
5644 continue;
5645
5646 bool IsFriendly = m_caster->IsFriendlyTo(target);
5647 // positive spells distribute threat among all units that are in combat with target, like healing
5649 target->getHostileRefMgr().threatAssist(m_caster, threatToAdd, m_spellInfo);
5650 // for negative spells threat gets distributed among affected targets
5651 else if (!m_spellInfo->_IsPositiveSpell() && !IsFriendly && target->CanHaveThreatList())
5652 target->AddThreat(m_caster, threatToAdd, m_spellInfo->GetSchoolMask(), m_spellInfo);
5653 }
5654 LOG_DEBUG("spells.aura", "Spell {}, added an additional {} threat for {} {} target(s)", m_spellInfo->Id, threat, m_spellInfo->_IsPositiveSpell() ? "assisting" : "harming", uint32(m_UniqueTargetInfo.size()));
5655}
@ SPELL_ATTR0_CU_NO_INITIAL_THREAT
Definition SpellInfo.h:181
static bool IsFriendly(Creature *piece, Creature *target)
Definition boss_chess_event.cpp:180
bool _IsPositiveSpell() const
Definition SpellInfo.cpp:2838
Definition SpellMgr.h:385

References SpellInfo::_IsPositiveSpell(), Unit::AddThreat(), BASE_ATTACK, Unit::CanHaveThreatList(), Unit::getHostileRefMgr(), SpellInfo::GetSchoolMask(), Unit::GetTotalAttackPowerValue(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, IsFriendly(), Unit::IsFriendlyTo(), LOG_DEBUG, m_caster, m_spellInfo, m_UniqueTargetInfo, SPELL_ATTR0_CU_NO_INITIAL_THREAT, SPELL_ATTR1_NO_THREAT, SPELL_ATTR3_SUPPRESS_TARGET_PROCS, SPELL_MISS_NONE, SpellInfo::SpellLevel, sSpellMgr, and HostileRefMgr::threatAssist().

Referenced by _handle_immediate_phase().

◆ HasGlobalCooldown()

bool Spell::HasGlobalCooldown ( ) const
protected

◆ HasTriggeredCastFlag()

◆ HaveTargetsForEffect()

bool Spell::HaveTargetsForEffect ( uint8  effect) const
8147{
8148 for (std::list<TargetInfo>::const_iterator itr = m_UniqueTargetInfo.begin(); itr != m_UniqueTargetInfo.end(); ++itr)
8149 if (itr->effectMask & (1 << effect))
8150 return true;
8151
8152 for (std::list<GOTargetInfo>::const_iterator itr = m_UniqueGOTargetInfo.begin(); itr != m_UniqueGOTargetInfo.end(); ++itr)
8153 if (itr->effectMask & (1 << effect))
8154 return true;
8155
8156 for (std::list<ItemTargetInfo>::const_iterator itr = m_UniqueItemInfo.begin(); itr != m_UniqueItemInfo.end(); ++itr)
8157 if (itr->effectMask & (1 << effect))
8158 return true;
8159
8160 return false;
8161}

References m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

◆ InitEffectExecuteData()

void Spell::InitEffectExecuteData ( uint8  effIndex)
protected
8529{
8530 ASSERT(effIndex < MAX_SPELL_EFFECTS);
8531 if (!m_effectExecuteData[effIndex])
8532 {
8533 m_effectExecuteData[effIndex] = new ByteBuffer(0x20);
8534 // first dword - target counter
8535 *m_effectExecuteData[effIndex] << uint32(1);
8536 }
8537 else
8538 {
8539 // increase target counter by one
8540 uint32 count = (*m_effectExecuteData[effIndex]).read<uint32>(0);
8541 (*m_effectExecuteData[effIndex]).put<uint32>(0, ++count);
8542 }
8543}

References ASSERT, m_effectExecuteData, and MAX_SPELL_EFFECTS.

Referenced by ExecuteLogEffectCreateItem(), ExecuteLogEffectDestroyItem(), ExecuteLogEffectDurabilityDamage(), ExecuteLogEffectExtraAttacks(), ExecuteLogEffectInterruptCast(), ExecuteLogEffectOpenLock(), ExecuteLogEffectResurrect(), ExecuteLogEffectSummonObject(), ExecuteLogEffectTakeTargetPower(), and ExecuteLogEffectUnsummonObject().

◆ InitExplicitTargets()

void Spell::InitExplicitTargets ( SpellCastTargets const &  targets)
718{
719 m_targets = targets;
720 // this function tries to correct spell explicit targets for spell
721 // client doesn't send explicit targets correctly sometimes - we need to fix such spells serverside
722 // this also makes sure that we correctly send explicit targets to client (removes redundant data)
723 uint32 neededTargets = m_spellInfo->GetExplicitTargetMask();
724
725 if (WorldObject* target = m_targets.GetObjectTarget())
726 {
727 // check if object target is valid with needed target flags
728 // for unit case allow corpse target mask because player with not released corpse is a unit target
729 if ((target->ToUnit() && !(neededTargets & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK)))
730 || (target->ToGameObject() && !(neededTargets & TARGET_FLAG_GAMEOBJECT_MASK))
731 || (target->ToCorpse() && !(neededTargets & TARGET_FLAG_CORPSE_MASK)))
733 }
734 else
735 {
736 // try to select correct unit target if not provided by client or by serverside cast
737 if (neededTargets & (TARGET_FLAG_UNIT_MASK))
738 {
739 Unit* unit = nullptr;
740 // try to use player selection as a target
741 if (Player* playerCaster = m_caster->ToPlayer())
742 {
743 // selection has to be found and to be valid target for the spell
744 if (Unit* selectedUnit = ObjectAccessor::GetUnit(*m_caster, playerCaster->GetTarget()))
746 unit = selectedUnit;
747 }
748 // try to use attacked unit as a target
749 else if ((m_caster->IsCreature()) && neededTargets & (TARGET_FLAG_UNIT_ENEMY | TARGET_FLAG_UNIT))
750 unit = m_caster->GetVictim();
751
752 // didn't find anything - let's use self as target
753 if (!unit && neededTargets & (TARGET_FLAG_UNIT_RAID | TARGET_FLAG_UNIT_PARTY | TARGET_FLAG_UNIT_ALLY))
754 unit = m_caster;
755
757 }
758 }
759
760 // check if spell needs dst target
761 if (neededTargets & TARGET_FLAG_DEST_LOCATION)
762 {
763 // and target isn't set
764 if (!m_targets.HasDst())
765 {
766 // try to use unit target if provided
767 if (WorldObject* target = targets.GetObjectTarget())
768 m_targets.SetDst(*target);
769 // or use self if not available
770 else
772 }
773 }
774 else
776
777 if (neededTargets & TARGET_FLAG_SOURCE_LOCATION)
778 {
779 if (!targets.HasSrc())
781 }
782 else
784}
@ TARGET_FLAG_UNIT_RAID
Definition SpellInfo.h:49
@ TARGET_FLAG_UNIT_ALLY
Definition SpellInfo.h:55
@ TARGET_FLAG_SOURCE_LOCATION
Definition SpellInfo.h:52
@ TARGET_FLAG_CORPSE_MASK
Definition SpellInfo.h:72
@ TARGET_FLAG_UNIT_PARTY
Definition SpellInfo.h:50
void RemoveDst()
Definition Spell.cpp:448
void RemoveSrc()
Definition Spell.cpp:391

References SpellInfo::CheckExplicitTarget(), SpellInfo::GetExplicitTargetMask(), SpellCastTargets::GetObjectTarget(), Unit::GetTarget(), ObjectAccessor::GetUnit(), Unit::GetVictim(), SpellCastTargets::HasDst(), SpellCastTargets::HasSrc(), Object::IsCreature(), m_caster, m_spellInfo, m_targets, SpellCastTargets::RemoveDst(), SpellCastTargets::RemoveObjectTarget(), SpellCastTargets::RemoveSrc(), SpellCastTargets::SetDst(), SpellCastTargets::SetSrc(), SpellCastTargets::SetUnitTarget(), SPELL_CAST_OK, TARGET_FLAG_CORPSE_MASK, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_SOURCE_LOCATION, TARGET_FLAG_UNIT, TARGET_FLAG_UNIT_ALLY, TARGET_FLAG_UNIT_ENEMY, TARGET_FLAG_UNIT_MASK, TARGET_FLAG_UNIT_PARTY, TARGET_FLAG_UNIT_RAID, and Object::ToPlayer().

Referenced by Player::CastItemUseSpell(), and prepare().

◆ IsAutoActionResetSpell()

bool Spell::IsAutoActionResetSpell ( ) const
Todo:
changed SPELL_INTERRUPT_FLAG_AUTOATTACK -> SPELL_INTERRUPT_FLAG_INTERRUPT to fix compile - is this check correct at all?
8121{
8124 {
8125 return false;
8126 }
8127
8129 {
8130 return false;
8131 }
8132
8133 return true;
8134}
@ SPELL_ATTR6_DOESNT_RESET_SWING_TIMER_IF_INSTANT
Definition SharedDefines.h:640

References SpellInfo::HasAttribute(), SpellInfo::InterruptFlags, IsTriggered(), m_casttime, m_spellInfo, SPELL_ATTR6_DOESNT_RESET_SWING_TIMER_IF_INSTANT, and SPELL_INTERRUPT_FLAG_INTERRUPT.

Referenced by _cast().

◆ IsAutoRepeat()

bool Spell::IsAutoRepeat ( ) const
inline

◆ IsChannelActive()

bool Spell::IsChannelActive ( ) const
inline
@ UNIT_CHANNEL_SPELL
Definition UpdateFields.h:94

References Object::GetUInt32Value(), m_caster, and UNIT_CHANNEL_SPELL.

Referenced by Creature::IsMovementPreventedByCasting().

◆ isDelayableNoMore()

bool Spell::isDelayableNoMore ( )
inlineprotected
653 {
654 if (m_delayAtDamageCount >= 2)
655 return true;
656
658 return false;
659 }

References m_delayAtDamageCount.

Referenced by Delayed(), and DelayedChannel().

◆ IsDeletable()

◆ IsIgnoringCooldowns()

bool Spell::IsIgnoringCooldowns ( ) const

◆ IsInterruptable()

bool Spell::IsInterruptable ( ) const
inline
584{ return !m_executedCurrently; }

References m_executedCurrently.

Referenced by Unit::InterruptSpell().

◆ IsNeedSendToClient()

◆ IsNextMeleeSwingSpell()

bool Spell::IsNextMeleeSwingSpell ( ) const

◆ IsTriggered()

◆ IsValidDeadOrAliveTarget()

bool Spell::IsValidDeadOrAliveTarget ( Unit const *  target) const
protected
8269{
8270 if (target->IsAlive())
8272
8274}
bool IsRequiringDeadTarget() const
Definition SpellInfo.cpp:1217
bool IsAllowingDeadTarget() const
Definition SpellInfo.cpp:1222

References Unit::IsAlive(), SpellInfo::IsAllowingDeadTarget(), SpellInfo::IsRequiringDeadTarget(), and m_spellInfo.

Referenced by UpdateChanneledTargetList().

◆ LoadScripts()

void Spell::LoadScripts ( )
8552{
8553 if (_scriptsLoaded)
8554 return;
8555 _scriptsLoaded = true;
8556 sScriptMgr->CreateSpellScripts(m_spellInfo->Id, m_loadedScripts);
8557 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end();)
8558 {
8559 if (!(*itr)->_Load(this))
8560 {
8561 std::list<SpellScript*>::iterator bitr = itr;
8562 ++itr;
8563 delete (*bitr);
8564 m_loadedScripts.erase(bitr);
8565 continue;
8566 }
8567 LOG_DEBUG("spells.aura", "Spell::LoadScripts: Script `{}` for spell `{}` is loaded now", (*itr)->_GetScriptName()->c_str(), m_spellInfo->Id);
8568 (*itr)->Register();
8569 ++itr;
8570 }
8571}

References _scriptsLoaded, SpellInfo::Id, LOG_DEBUG, m_loadedScripts, m_spellInfo, and sScriptMgr.

Referenced by WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), prepare(), and PetAI::UpdateAI().

◆ OnSpellLaunch()

void Spell::OnSpellLaunch ( )
8957{
8958 if (!m_caster || !m_caster->IsInWorld())
8959 return;
8960
8961 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(24390);
8962
8963 // Make sure the player is sending a valid GO target and lock ID. SPELL_EFFECT_OPEN_LOCK
8964 // can succeed with a lockId of 0
8965 if (m_spellInfo->Id == 21651)
8966 {
8967 if (GameObject* go = m_targets.GetGOTarget())
8968 {
8969 LockEntry const* lockInfo = sLockStore.LookupEntry(go->GetGOInfo()->GetLockId());
8970 if (lockInfo && lockInfo->Index[1] == LOCKTYPE_SLOW_OPEN)
8971 {
8972 Spell* visual = new Spell(m_caster, spellInfo, TRIGGERED_NONE);
8973 visual->prepare(&m_targets);
8974 }
8975 }
8976 }
8977}
@ LOCKTYPE_SLOW_OPEN
Definition SharedDefines.h:2619
@ TRIGGERED_NONE
Definition SpellDefines.h:133

References SpellCastTargets::GetGOTarget(), SpellInfo::Id, LockEntry::Index, Object::IsInWorld(), LOCKTYPE_SLOW_OPEN, m_caster, m_spellInfo, m_targets, prepare(), sLockStore, sSpellMgr, and TRIGGERED_NONE.

Referenced by prepare().

◆ prepare()

SpellCastResult Spell::prepare ( SpellCastTargets const *  targets,
AuraEffect const *  triggeredByAura = nullptr 
)

m_castItemGUID &&

3483{
3484 if (m_CastItem)
3485 {
3487 }
3488 else
3489 {
3491 }
3492
3493 InitExplicitTargets(*targets);
3494
3495 if (!sScriptMgr->CanPrepare(this, targets, triggeredByAura))
3496 {
3497 finish(false);
3498 return SPELL_FAILED_UNKNOWN;
3499 }
3500
3501 // Fill aura scaling information
3503 {
3504 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3505 {
3506 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA ||
3509 {
3510 // Change aura with ranks only if basepoints are taken from spellInfo and aura is positive
3512 {
3513 m_auraScaleMask |= (1 << i);
3514 if (m_spellValue->EffectBasePoints[i] != m_spellInfo->Effects[i].BasePoints)
3515 {
3516 m_auraScaleMask = 0;
3517 break;
3518 }
3519 }
3520 }
3521 }
3522 }
3523
3525
3526 if (triggeredByAura)
3527 {
3528 m_triggeredByAuraSpell.Init(triggeredByAura);
3529 }
3530
3531 // create and add update event for this spell
3532 _spellEvent = new SpellEvent(this);
3534
3535 if (sDisableMgr->IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, m_caster))
3536 {
3538 finish(false);
3540 }
3541
3542 //Prevent casting at cast another spell (ServerSide check)
3544 {
3546 finish(false);
3548 }
3549
3550 LoadScripts();
3551
3552 OnSpellLaunch();
3553
3555
3556 // Set combo point requirement
3558 m_needComboPoints = false;
3559
3560 SpellCastResult result = CheckCast(true);
3561 if (result != SPELL_CAST_OK && !IsAutoRepeat()) //always cast autorepeat dummy for triggering
3562 {
3563 // Periodic auras should be interrupted when aura triggers a spell which can't be cast
3564 // for example bladestorm aura should be removed on disarm as of patch 3.3.5
3565 // channeled periodic spells should be affected by this (arcane missiles, penance, etc)
3566 // a possible alternative sollution for those would be validating aura target on unit state change
3567 if (m_caster->IsPlayer() && triggeredByAura && triggeredByAura->IsPeriodic() && !triggeredByAura->GetBase()->IsPassive())
3568 {
3570 triggeredByAura->GetBase()->SetDuration(0);
3571 }
3572
3573 // Allows to cast melee attack spell if result is SPELL_FAILED_OUT_OF_RANGE
3575 {
3576 SendCastResult(result);
3577
3578 finish(false);
3579 return result;
3580 }
3581 }
3582
3583 // Prepare data for triggers
3584 prepareDataForTriggerSystem(triggeredByAura);
3585
3586 // calculate cast time (calculated after first CheckCast check to prevent charge counting for first CheckCast fail)
3588
3589 if (m_caster->IsPlayer())
3591 m_casttime = 0;
3592
3593 // don't allow channeled spells / spells with cast time to be casted while moving
3594 // (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in)
3596 {
3597 // 1. Has casttime, 2. Or doesn't have flag to allow action during channel
3599 {
3601 finish(false);
3602 return SPELL_FAILED_MOVING;
3603 }
3604 }
3605
3606 // xinef: if spell have nearby target entry only, do not allow to cast if no targets are found
3607 if (m_CastItem)
3608 {
3609 bool selectTargets = false;
3610 bool nearbyDest = false;
3611
3612 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
3613 {
3614 if (!m_spellInfo->Effects[i].IsEffect())
3615 continue;
3616
3617 if (m_spellInfo->Effects[i].TargetA.GetSelectionCategory() != TARGET_SELECT_CATEGORY_NEARBY || m_spellInfo->Effects[i].TargetA.GetCheckType() != TARGET_CHECK_ENTRY)
3618 {
3619 selectTargets = false;
3620 break;
3621 }
3622
3623 if (m_spellInfo->Effects[i].TargetA.GetObjectType() == TARGET_OBJECT_TYPE_DEST)
3624 {
3625 nearbyDest = true;
3626 }
3627
3628 // xinef: by default set it to false, and to true if any valid target is found
3629 selectTargets = true;
3630 }
3631
3632 if (selectTargets)
3633 {
3635 _spellTargetsSelected = true;
3636 bool spellFailed = false;
3637
3638 if (m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty())
3639 {
3640 // no valid nearby target unit or game object found; check if nearby destination type
3641 if (nearbyDest)
3642 {
3643 if (!m_targets.HasDst())
3644 {
3645 // no valid target destination
3646 spellFailed = true;
3647 }
3648 }
3649 else
3650 {
3651 spellFailed = true;
3652 }
3653 }
3654
3655 if (spellFailed)
3656 {
3658 finish(false);
3660 }
3661 }
3662 }
3663
3664 // set timer base at cast time
3665 ReSetTimer();
3666
3667 LOG_DEBUG("spells.aura", "Spell::prepare: spell id {} source {} caster {} customCastFlags {} mask {}", m_spellInfo->Id, m_caster->GetEntry(), m_originalCaster ? m_originalCaster->GetEntry() : -1, _triggeredCastFlags, m_targets.GetTargetMask());
3668
3670 {
3672 }
3673
3674 //Containers for channeled spells have to be set
3675 //TODO:Apply this to all casted spells if needed
3676 // Why check duration? 29350: channelled triggers channelled
3678 cast(true);
3679 else
3680 {
3681 // stealth must be removed at cast starting (at show channel bar)
3682 // skip triggered spell (item equip spell casting and other not explicit character casts/item uses)
3684 {
3685 // Farsight spells exception
3686 uint32 exceptSpellId = 0;
3688 {
3689 exceptSpellId = m_spellInfo->Id;
3690 }
3691
3694 }
3695
3698
3699 // set target for proper facing
3701 {
3704 {
3705 // Xinef: Creature should focus to cast target if there is explicit target or self if casting positive spell
3706 // Xinef: Creature should not rotate when casting spell... based on halion behavior
3708 }
3709 }
3710
3711 //item: first cast may destroy item and second cast causes crash
3712 // xinef: removed !m_spellInfo->StartRecoveryTime
3713 // second los check failed in events
3714 // xinef: removed itemguid check, currently there is no such item in database
3716 cast(true);
3717
3720 }
3721
3722 sScriptMgr->OnSpellPrepare(this, m_caster, m_spellInfo);
3723
3724 return SPELL_CAST_OK;
3725}
@ CHEAT_CASTTIME
Definition Player.h:996
@ SPELL_EFFECT_APPLY_AREA_AURA_PARTY
Definition SharedDefines.h:824
@ SPELL_EFFECT_APPLY_AREA_AURA_RAID
Definition SharedDefines.h:854
@ SPELL_ATTR0_ALLOW_WHILE_SITTING
Definition SharedDefines.h:420
@ AURA_INTERRUPT_FLAG_SPELL_ATTACK
Definition SpellDefines.h:56
@ AURA_INTERRUPT_FLAG_CAST
Definition SpellDefines.h:45
@ TRIGGERED_IGNORE_AURA_SCALING
Will not take away cast item or update related achievement criteria.
Definition SpellDefines.h:138
@ TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS
In Spell::prepare, will be cast directly without setting containers for executed spell.
Definition SpellDefines.h:142
@ TRIGGERED_IGNORE_COMBO_POINTS
Will not check if a current cast is in progress.
Definition SpellDefines.h:140
@ SPELL_INTERRUPT_FLAG_MOVEMENT
Definition SpellDefines.h:26
@ TARGET_SELECT_CATEGORY_NEARBY
Definition SpellInfo.h:81
@ TARGET_OBJECT_TYPE_DEST
Definition SpellInfo.h:101
void FocusTarget(Spell const *focusSpell, WorldObject const *target)
Definition Creature.cpp:3567
Definition Spell.cpp:519
bool IsActionAllowedChannel() const
Definition SpellInfo.cpp:1256
int32 GetMaxDuration() const
Definition SpellInfo.cpp:2352
uint32 Attributes
Definition SpellInfo.h:325
bool IsBreakingStealth() const
Definition SpellInfo.cpp:1266
void LoadScripts()
Definition Spell.cpp:8551
void cast(bool skipCheck=false)
Definition Spell.cpp:3800
void prepareDataForTriggerSystem(AuraEffect const *triggeredByAura)
Definition Spell.cpp:2293
void SendSpellStart()
Definition Spell.cpp:4746
void TriggerGlobalCooldown()
Definition Spell.cpp:8895
void OnSpellLaunch()
Definition Spell.cpp:8956
CurrentSpellTypes GetCurrentContainer() const
Definition Spell.cpp:7956
void ReSetTimer()
Definition Spell.h:573
void InitExplicitTargets(SpellCastTargets const &targets)
Definition Spell.cpp:717
void SetCurrentCastedSpell(Spell *pSpell)
Definition Unit.cpp:4010
bool IsSitState() const
Definition Unit.cpp:16794
void Init(AuraEffect const *aurEff)
Definition Spell.cpp:8979

References _spellEvent, _spellTargetsSelected, _triggeredCastFlags, EventProcessor::AddEvent(), SpellInfo::Attributes, AURA_INTERRUPT_FLAG_CAST, AURA_INTERRUPT_FLAG_NOT_SEATED, AURA_INTERRUPT_FLAG_SPELL_ATTACK, SpellInfo::AuraInterruptFlags, SpellInfo::CalcCastTime(), SpellInfo::CalcPowerCost(), EventProcessor::CalculateTime(), cast(), CHEAT_CASTTIME, CheckCast(), CURRENT_GENERIC_SPELL, DISABLE_TYPE_SPELL, EFFECT_0, SpellValue::EffectBasePoints, SpellInfo::Effects, ObjectGuid::Empty, finish(), Creature::FocusTarget(), AuraEffect::GetBase(), Player::GetCommandStatus(), GetCurrentContainer(), Object::GetEntry(), Object::GetGUID(), SpellInfo::GetMaxDuration(), SpellCastTargets::GetObjectTarget(), SpellCastTargets::GetTargetMask(), SpellCastTargets::HasDst(), SpellInfo::HasEffect(), HasTriggeredCastFlag(), SpellInfo::Id, TriggeredByAuraSpellData::Init(), InitExplicitTargets(), SpellInfo::InterruptFlags, SpellInfo::IsActionAllowedChannel(), IsAutoRepeat(), SpellInfo::IsBreakingStealth(), SpellInfo::IsChanneled(), Unit::IsControlledByPlayer(), Object::IsCreature(), Creature::IsInEvadeMode(), Unit::isMoving(), IsNextMeleeSwingSpell(), Unit::IsNonMeleeSpellCast(), Aura::IsPassive(), SpellInfo::IsPassive(), AuraEffect::IsPeriodic(), Object::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsPositiveEffect(), Unit::IsSitState(), Unit::IsTotem(), IsTriggered(), LoadScripts(), LOG_DEBUG, m_auraScaleMask, m_cast_count, m_caster, m_CastItem, m_castItemGUID, m_casttime, WorldObject::m_Events, m_needComboPoints, m_originalCaster, m_powerCost, m_spellInfo, m_spellSchoolMask, m_spellState, m_spellValue, m_targets, m_triggeredByAuraSpell, m_UniqueGOTargetInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, OnSpellLaunch(), prepareDataForTriggerSystem(), Unit::RemoveAurasWithInterruptFlags(), ReSetTimer(), sDisableMgr, SelectSpellTargets(), SendCastResult(), SendChannelUpdate(), SendSpellStart(), Unit::SetCurrentCastedSpell(), Aura::SetDuration(), Unit::SetStandState(), SPELL_ATTR0_ALLOW_WHILE_SITTING, SPELL_CAST_OK, SPELL_EFFECT_ADD_FARSIGHT, SPELL_EFFECT_APPLY_AREA_AURA_PARTY, SPELL_EFFECT_APPLY_AREA_AURA_RAID, SPELL_EFFECT_APPLY_AURA, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_MOVING, SPELL_FAILED_OUT_OF_RANGE, SPELL_FAILED_SPELL_IN_PROGRESS, SPELL_FAILED_SPELL_UNAVAILABLE, SPELL_FAILED_UNKNOWN, SPELL_INTERRUPT_FLAG_MOVEMENT, SPELL_STATE_PREPARING, SpellInfo::SpellLevel, sScriptMgr, TARGET_CHECK_ENTRY, TARGET_OBJECT_TYPE_DEST, TARGET_SELECT_CATEGORY_NEARBY, Object::ToCreature(), Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS, TRIGGERED_IGNORE_AURA_SCALING, TRIGGERED_IGNORE_CAST_IN_PROGRESS, TRIGGERED_IGNORE_COMBO_POINTS, TRIGGERED_IGNORE_GCD, TRIGGERED_IGNORE_SET_FACING, TriggerGlobalCooldown(), and UNIT_STAND_STATE_STAND.

Referenced by Unit::_UpdateAutoRepeatSpell(), Player::CastItemUseSpell(), Unit::CastSpell(), EffectEnchantItemTmp(), WorldSession::HandleAcceptTradeOpcode(), WorldSession::HandleCastSpellOpcode(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), OnSpellLaunch(), and PetAI::UpdateAI().

◆ prepareDataForTriggerSystem()

void Spell::prepareDataForTriggerSystem ( AuraEffect const *  triggeredByAura)
protected
2294{
2295 //==========================================================================================
2296 // Now fill data for trigger system, need know:
2297 // can spell trigger another or not (m_canTrigger)
2298 // Create base triggers flags for Attacker and Victim (m_procAttacker, m_procVictim and m_procEx)
2299 //==========================================================================================
2300
2302 // Get data for type of attack and fill base info for trigger
2303 switch (m_spellInfo->DmgClass)
2304 {
2307 if (m_attackType == OFF_ATTACK)
2309 else
2312 break;
2314 // Auto attack
2316 {
2319 }
2320 else // Ranged spell attack
2321 {
2324 }
2325 break;
2326 default:
2329 && m_spellInfo->HasAttribute(SPELL_ATTR2_AUTO_REPEAT)) // Wands auto attack
2330 {
2333 }
2334 // For other spells trigger procflags are set in Spell::DoAllEffectOnTarget
2335 // Because spell positivity is dependant on target
2336 }
2338
2339 // Hunter trap spells - activation proc for Lock and Load, Entrapment and Misdirection
2341 (m_spellInfo->SpellFamilyFlags[0] & 0x18 || // Freezing and Frost Trap, Freezing Arrow
2342 m_spellInfo->Id == 57879 || m_spellInfo->Id == 45145 || // Snake Trap - done this way to avoid double proc
2343 m_spellInfo->SpellFamilyFlags[2] & 0x00064000)) // Explosive and Immolation Trap
2344 {
2346 }
2347
2348 /* Effects which are result of aura proc from triggered spell cannot proc
2349 to prevent chain proc of these spells */
2350
2351 // Hellfire Effect - trigger as DOT
2353 {
2356 }
2357
2358 // Ranged autorepeat attack is set as triggered spell - ignore it
2360 {
2367 }
2368 // Totem casts require spellfamilymask defined in spell_proc_event to proc
2371}
@ SPELL_ATTR2_ACTIVE_THREAT
Definition SharedDefines.h:497
@ SPELL_ATTR3_NOT_A_PROC
Definition SharedDefines.h:513
@ TRIGGERED_DISALLOW_PROC_EVENTS
Will ignore caster aura restrictions or requirements.
Definition SpellDefines.h:148
@ PROC_EX_NONE
Definition SpellMgr.h:193
@ PROC_EX_INTERNAL_CANT_PROC
Definition SpellMgr.h:218
@ PROC_EX_INTERNAL_TRIGGERED
Definition SpellMgr.h:221
@ PROC_EX_INTERNAL_REQ_FAMILY
Definition SpellMgr.h:222
@ PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS
Definition SpellMgr.h:119
@ PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK
Definition SpellMgr.h:117
@ PROC_FLAG_DONE_PERIODIC
Definition SpellMgr.h:134
@ PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS
Definition SpellMgr.h:113
@ PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS
Definition SpellMgr.h:120
@ PROC_FLAG_TAKEN_PERIODIC
Definition SpellMgr.h:135
@ PROC_FLAG_DONE_MAINHAND_ATTACK
Definition SpellMgr.h:140
@ PROC_FLAG_DONE_RANGED_AUTO_ATTACK
Definition SpellMgr.h:116
@ PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS
Definition SpellMgr.h:114
@ PROC_FLAG_DONE_TRAP_ACTIVATION
Definition SpellMgr.h:138
@ PROC_FLAG_DONE_OFFHAND_ATTACK
Definition SpellMgr.h:141

References SpellInfo::DmgClass, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, SpellInfo::HasAttribute(), HasTriggeredCastFlag(), SpellInfo::Id, Unit::IsControlledByPlayer(), Object::IsCreature(), Unit::IsTotem(), ITEM_CLASS_WEAPON, ITEM_SUBCLASS_WEAPON_WAND, m_attackType, m_caster, m_originalCaster, m_procAttacker, m_procEx, m_procVictim, m_spellInfo, OFF_ATTACK, PROC_EX_INTERNAL_CANT_PROC, PROC_EX_INTERNAL_REQ_FAMILY, PROC_EX_INTERNAL_TRIGGERED, PROC_EX_NONE, PROC_FLAG_DONE_MAINHAND_ATTACK, PROC_FLAG_DONE_OFFHAND_ATTACK, PROC_FLAG_DONE_PERIODIC, PROC_FLAG_DONE_RANGED_AUTO_ATTACK, PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS, PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS, PROC_FLAG_DONE_TRAP_ACTIVATION, PROC_FLAG_TAKEN_PERIODIC, PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK, PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS, PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS, SPELL_ATTR2_ACTIVE_THREAT, SPELL_ATTR2_AUTO_REPEAT, SPELL_ATTR3_NOT_A_PROC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELLFAMILY_HUNTER, SPELLFAMILY_WARLOCK, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, Object::ToCreature(), and TRIGGERED_DISALLOW_PROC_EVENTS.

Referenced by prepare().

◆ PrepareScriptHitHandlers()

void Spell::PrepareScriptHitHandlers ( )
protected
8632{
8633 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8634 (*scritr)->_InitHit();
8635}

References m_loadedScripts.

Referenced by _cast(), _handle_immediate_phase(), DoAllEffectOnTarget(), DoAllEffectOnTarget(), and DoAllEffectOnTarget().

◆ PrepareTargetProcessing()

void Spell::PrepareTargetProcessing ( )
protected

◆ PrepareTriggersExecutedOnHit()

void Spell::PrepareTriggersExecutedOnHit ( )
protected
Todo:
: move this to scripts
Todo:
: move this to scripts
8806{
8809 {
8810 SpellInfo const* excludeCasterSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeCasterAuraSpell);
8811 if (excludeCasterSpellInfo && !excludeCasterSpellInfo->IsPositive())
8813 SpellInfo const* excludeTargetSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeTargetAuraSpell);
8814 if (excludeTargetSpellInfo && !excludeTargetSpellInfo->IsPositive())
8816 }
8817
8820 {
8822 {
8823 if (m_spellInfo->SpellFamilyFlags[1] & 0x40000000)
8824 {
8826 for(Unit::AuraEffectList::const_iterator itr = mVindication.begin(); itr != mVindication.end(); ++itr)
8827 {
8828 if ((*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 26017 )
8829 {
8830 m_preCastSpell = 26017;
8831 break;
8832 }
8833 else if ((*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 67 )
8834 m_preCastSpell = 67;
8835 }
8836 }
8837 break;
8838 }
8839 case SPELLFAMILY_DRUID:
8840 {
8841 // Faerie Fire (Feral)
8843 m_preCastSpell = 60089;
8844
8845 break;
8846 }
8847 }
8848
8849 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras:
8850 // save auras which were present on spell caster on cast, to prevent triggered auras from affecting caster
8851 // and to correctly calculate proc chance when combopoints are present
8853 for (Unit::AuraEffectList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)
8854 {
8855 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
8856 continue;
8857 SpellInfo const* auraSpellInfo = (*i)->GetSpellInfo();
8858 uint32 auraSpellIdx = (*i)->GetEffIndex();
8859 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(auraSpellInfo->Effects[auraSpellIdx].TriggerSpell))
8860 {
8861 // calculate the chance using spell base amount, because aura amount is not updated on combo-points change
8862 // this possibly needs fixing
8863 int32 auraBaseAmount = (*i)->GetBaseAmount();
8864 // proc chance is stored in effect amount
8865 int32 chance = m_caster->CalculateSpellDamage(nullptr, auraSpellInfo, auraSpellIdx, &auraBaseAmount);
8866 // build trigger and add to the list
8867 HitTriggerSpell spellTriggerInfo;
8868 spellTriggerInfo.triggeredSpell = spellInfo;
8869 spellTriggerInfo.triggeredByAura = auraSpellInfo;
8870 spellTriggerInfo.triggeredByEffIdx = (*i)->GetEffIndex();
8871 spellTriggerInfo.chance = chance * (*i)->GetBase()->GetStackAmount();
8872 m_hitTriggerSpells.push_back(spellTriggerInfo);
8873 }
8874 }
8875}
@ SPELL_AURA_PROC_TRIGGER_SPELL
Definition SpellAuraDefines.h:105
@ SPELL_AURA_ADD_TARGET_TRIGGER
Definition SpellAuraDefines.h:172
@ FORM_DIREBEAR
Definition UnitDefines.h:77
@ FORM_BEAR
Definition UnitDefines.h:74
uint32 ExcludeTargetAuraSpell
Definition SpellInfo.h:347

References Unit::CalculateSpellDamage(), Spell::HitTriggerSpell::chance, EFFECT_0, SpellInfo::Effects, SpellInfo::ExcludeCasterAuraSpell, SpellInfo::ExcludeTargetAuraSpell, FORM_BEAR, FORM_DIREBEAR, Unit::GetAuraEffectsByType(), Unit::GetShapeshiftForm(), SpellInfo::Id, SpellInfo::IsPositive(), m_caster, m_hitTriggerSpells, m_preCastSpell, m_spellInfo, SPELL_AURA_ADD_TARGET_TRIGGER, SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_DRUID, SPELLFAMILY_PALADIN, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, sSpellMgr, Spell::HitTriggerSpell::triggeredByAura, Spell::HitTriggerSpell::triggeredByEffIdx, and Spell::HitTriggerSpell::triggeredSpell.

Referenced by _cast().

◆ RecalculateDelayMomentForDst()

void Spell::RecalculateDelayMomentForDst ( )
921{
924}
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:27
void ModifyEventTime(BasicEvent *event, Milliseconds newTime)
Definition EventProcessor.cpp:145
uint64 CalculateDelayMomentForDst() const
Definition Spell.cpp:899
uint64 GetDelayStart() const
Definition Spell.h:586

References _spellEvent, CalculateDelayMomentForDst(), GetDelayStart(), m_caster, m_delayMoment, WorldObject::m_Events, and EventProcessor::ModifyEventTime().

◆ ReSetTimer()

void Spell::ReSetTimer ( )
inline
573{ m_timer = m_casttime > 0 ? m_casttime : 0; }

References m_casttime, and m_timer.

Referenced by prepare().

◆ SearchAreaTargets()

void Spell::SearchAreaTargets ( std::list< WorldObject * > &  targets,
float  range,
Position const *  position,
Unit referer,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectionType,
std::shared_ptr< ConditionList condList 
)
2186{
2187 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2188 if (!containerTypeMask)
2189 return;
2190 Acore::WorldObjectSpellAreaTargetCheck check(range, position, m_caster, referer, m_spellInfo, selectionType, condList);
2191 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
2192 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> > (searcher, containerTypeMask, m_caster, position, range);
2193}
uint32 GetSearcherTypeMask(SpellTargetObjectTypes objType, std::shared_ptr< ConditionList > condList)
Definition Spell.cpp:2122
Definition GridNotifiers.h:230

References GetSearcherTypeMask(), m_caster, and m_spellInfo.

Referenced by SearchChainTargets(), and SelectImplicitAreaTargets().

◆ SearchChainTargets()

void Spell::SearchChainTargets ( std::list< WorldObject * > &  targets,
uint32  chainTargets,
WorldObject target,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectType,
SpellTargetSelectionCategories  selectCategory,
std::shared_ptr< ConditionList condList,
bool  isChainHeal 
)
2200{
2201 // max dist for jump target selection
2202 float jumpRadius = 0.0f;
2203 switch (m_spellInfo->DmgClass)
2204 {
2206 // 7.5y for multi shot
2207 jumpRadius = 7.5f;
2208 break;
2210 // 5y for swipe, cleave and similar
2211 jumpRadius = 5.0f;
2212 break;
2215 // 12.5y for chain heal spell since 3.2 patch
2216 if (isChainHeal)
2217 jumpRadius = 12.5f;
2218 // 10y as default for magic chain spells
2219 else
2220 jumpRadius = 10.0f;
2221 break;
2222 }
2223
2224 // chain lightning/heal spells and similar - allow to jump at larger distance and go out of los
2228
2229 // max dist which spell can reach
2230 float searchRadius = jumpRadius;
2231 if (isBouncingFar)
2232 searchRadius *= chainTargets;
2233
2235 std::list<WorldObject*> tempTargets;
2236 SearchAreaTargets(tempTargets, searchRadius, chainSource, m_caster,
2237 objectType, selectType, condList);
2238 tempTargets.remove(target);
2239
2240 // remove targets which are always invalid for chain spells
2241 // for some spells allow only chain targets in front of caster (swipe for example)
2242 if (!isBouncingFar)
2243 tempTargets.remove_if([this](WorldObject* target) { return !m_caster->HasInArc(static_cast<float>(M_PI), target); });
2244
2245 while (chainTargets)
2246 {
2247 // try to get unit for next chain jump
2248 std::list<WorldObject*>::iterator foundItr = tempTargets.end();
2249 // get unit with highest hp deficit in dist
2250 if (isChainHeal)
2251 {
2252 uint32 maxHPDeficit = 0;
2253 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2254 {
2255 if (Unit* unit = (*itr)->ToUnit())
2256 {
2257 uint32 deficit = unit->GetMaxHealth() - unit->GetHealth();
2258 if (deficit > maxHPDeficit && chainSource->IsWithinDist(unit, jumpRadius) && chainSource->IsWithinLOSInMap(unit, VMAP::ModelIgnoreFlags::M2))
2259 {
2260 foundItr = itr;
2261 maxHPDeficit = deficit;
2262 }
2263 }
2264 }
2265 }
2266 // get closest object
2267 else
2268 {
2269 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2270 {
2271 if (foundItr == tempTargets.end())
2272 {
2273 if ((!isBouncingFar || chainSource->IsWithinDist(*itr, jumpRadius)) && chainSource->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2274 foundItr = itr;
2275 }
2276 else if (chainSource->GetDistanceOrder(*itr, *foundItr) && chainSource->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2277 foundItr = itr;
2278 }
2279 }
2280 // not found any valid target - chain ends
2281 if (foundItr == tempTargets.end())
2282 break;
2283
2285 chainSource = *foundItr;
2286
2287 targets.push_back(*foundItr);
2288 tempTargets.erase(foundItr);
2289 --chainTargets;
2290 }
2291}
@ SPELL_ATTR2_CHAIN_FROM_CASTER
Definition SharedDefines.h:479
@ SPELL_ATTR4_BOUNCY_CHAIN_MISSILES
Definition SharedDefines.h:559
void SearchAreaTargets(std::list< WorldObject * > &targets, float range, Position const *position, Unit *referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, std::shared_ptr< ConditionList > condList)
Definition Spell.cpp:2181
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true, bool useBoundingRadius=true) const
Definition Object.cpp:1321
bool GetDistanceOrder(WorldObject const *obj1, WorldObject const *obj2, bool is3D=true) const
Definition Object.cpp:1386

References SpellInfo::DmgClass, WorldObject::GetDistanceOrder(), SpellInfo::HasAttribute(), Position::HasInArc(), WorldObject::IsWithinDist(), WorldObject::IsWithinLOSInMap(), VMAP::M2, m_caster, m_spellInfo, SearchAreaTargets(), SPELL_ATTR2_CHAIN_FROM_CASTER, SPELL_ATTR4_BOUNCY_CHAIN_MISSILES, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_NONE, SPELL_DAMAGE_CLASS_RANGED, and Object::ToUnit().

Referenced by SelectImplicitChainTargets().

◆ SearchNearbyTarget()

WorldObject * Spell::SearchNearbyTarget ( float  range,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectionType,
std::shared_ptr< ConditionList condList = nullptr 
)
2170{
2171 WorldObject* target = nullptr;
2172 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2173 if (!containerTypeMask)
2174 return nullptr;
2175 Acore::WorldObjectSpellNearbyTargetCheck check(range, m_caster, m_spellInfo, selectionType, condList);
2177 SearchTargets<Acore::WorldObjectLastSearcher<Acore::WorldObjectSpellNearbyTargetCheck> > (searcher, containerTypeMask, m_caster, m_caster, range);
2178 return target;
2179}
Definition GridNotifiers.h:210

References GetSearcherTypeMask(), m_caster, and m_spellInfo.

Referenced by SelectImplicitNearbyTargets().

◆ SearchTargets()

template<class SEARCHER >
void Spell::SearchTargets ( SEARCHER &  searcher,
uint32  containerMask,
Unit referer,
Position const *  pos,
float  radius 
)
2160{
2161 if (!containerMask)
2162 return;
2163
2164 Cell::VisitObjects(pos->GetPositionX(), pos->GetPositionY(), referer->GetMap(), searcher, radius);
2165}

References WorldObject::GetMap(), Position::GetPositionX(), Position::GetPositionY(), and Cell::VisitObjects().

◆ SelectEffectImplicitTargets()

void Spell::SelectEffectImplicitTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32 processedEffectMask 
)
927{
928 if (!targetType.GetTarget())
929 return;
930
931 uint32 effectMask = 1 << effIndex;
932 // set the same target list for all effects
933 // some spells appear to need this, however this requires more research
934 switch (targetType.GetSelectionCategory())
935 {
939 {
940 // targets for effect already selected
941 if (effectMask & processedEffectMask)
942 {
943 return;
944 }
945
946 auto const& effects = GetSpellInfo()->Effects;
947
948 // choose which targets we can select at once
949 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
950 {
951 if (effects[j].IsEffect() &&
952 effects[effIndex].TargetA.GetTarget() == effects[j].TargetA.GetTarget() &&
953 effects[effIndex].TargetB.GetTarget() == effects[j].TargetB.GetTarget() &&
954 effects[effIndex].ImplicitTargetConditions == effects[j].ImplicitTargetConditions &&
955 effects[effIndex].CalcRadius(m_caster) == effects[j].CalcRadius(m_caster) &&
957 {
958 effectMask |= 1 << j;
959 }
960 }
961 processedEffectMask |= effectMask;
962 break;
963 }
964 default:
965 break;
966 }
967
968 switch (targetType.GetSelectionCategory())
969 {
971 SelectImplicitChannelTargets(effIndex, targetType);
972 break;
974 SelectImplicitNearbyTargets(effIndex, targetType, effectMask);
975 break;
977 SelectImplicitConeTargets(effIndex, targetType, effectMask);
978 break;
980 SelectImplicitAreaTargets(effIndex, targetType, effectMask);
981 break;
983 // just in case there is no dest, explanation in SelectImplicitDestDestTargets
984 CheckDst();
985
986 SelectImplicitTrajTargets(effIndex, targetType);
987 break;
989 switch (targetType.GetObjectType())
990 {
992 switch (targetType.GetReferenceType())
993 {
996 break;
997 default:
998 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_SRC");
999 break;
1000 }
1001 break;
1003 switch (targetType.GetReferenceType())
1004 {
1006 SelectImplicitCasterDestTargets(effIndex, targetType);
1007 break;
1009 SelectImplicitTargetDestTargets(effIndex, targetType);
1010 break;
1012 SelectImplicitDestDestTargets(effIndex, targetType);
1013 break;
1014 default:
1015 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_DEST");
1016 break;
1017 }
1018 break;
1019 default:
1020 switch (targetType.GetReferenceType())
1021 {
1023 SelectImplicitCasterObjectTargets(effIndex, targetType);
1024 break;
1026 SelectImplicitTargetObjectTargets(effIndex, targetType);
1027 break;
1028 default:
1029 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT");
1030 break;
1031 }
1032 break;
1033 }
1034 break;
1036 LOG_DEBUG("spells.aura", "SPELL: target type {}, found in spellID {}, effect {} is not implemented yet!", m_spellInfo->Id, effIndex, targetType.GetTarget());
1037 break;
1038 default:
1039 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target category");
1040 break;
1041 }
1042}
@ TARGET_SELECT_CATEGORY_CONE
Definition SpellInfo.h:82
@ TARGET_SELECT_CATEGORY_AREA
Definition SpellInfo.h:83
@ TARGET_SELECT_CATEGORY_DEFAULT
Definition SpellInfo.h:79
@ TARGET_SELECT_CATEGORY_NYI
Definition SpellInfo.h:78
@ TARGET_SELECT_CATEGORY_TRAJ
Definition SpellInfo.h:84
@ TARGET_SELECT_CATEGORY_CHANNEL
Definition SpellInfo.h:80
@ TARGET_OBJECT_TYPE_SRC
Definition SpellInfo.h:100
@ TARGET_REFERENCE_TYPE_TARGET
Definition SpellInfo.h:91
@ TARGET_REFERENCE_TYPE_CASTER
Definition SpellInfo.h:90
@ TARGET_REFERENCE_TYPE_DEST
Definition SpellInfo.h:94
void SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1730
void CheckDst()
Definition Spell.h:515
void SelectImplicitTrajTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1879
void SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition Spell.cpp:1214
void SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1693
void SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition Spell.cpp:1264
void SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1044
void SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1816
void SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1769
void SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition Spell.cpp:1100
bool CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck)
Definition Spell.cpp:8766
void SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1346

References ASSERT, CheckDst(), CheckScriptEffectImplicitTargets(), SpellInfo::Effects, SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellImplicitTargetInfo::GetSelectionCategory(), GetSpellInfo(), SpellImplicitTargetInfo::GetTarget(), SpellInfo::Id, LOG_DEBUG, m_caster, m_spellInfo, m_targets, MAX_SPELL_EFFECTS, SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTargetObjectTargets(), SelectImplicitTrajTargets(), SpellCastTargets::SetSrc(), TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_SRC, TARGET_REFERENCE_TYPE_CASTER, TARGET_REFERENCE_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_AREA, TARGET_SELECT_CATEGORY_CHANNEL, TARGET_SELECT_CATEGORY_CONE, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CATEGORY_NEARBY, TARGET_SELECT_CATEGORY_NYI, and TARGET_SELECT_CATEGORY_TRAJ.

Referenced by SelectSpellTargets().

◆ SelectEffectTypeImplicitTargets()

void Spell::SelectEffectTypeImplicitTargets ( uint8  effIndex)
Todo:
: this is a workaround - target shouldn't be stored in target map for those spells
Todo:
: this is a workaround - corpses should be added to spell target map too, but we can't do that so we add owner instead
2040{
2041 // special case for SPELL_EFFECT_SUMMON_RAF_FRIEND and SPELL_EFFECT_SUMMON_PLAYER
2043 switch (m_spellInfo->Effects[effIndex].Effect)
2044 {
2048 {
2050
2052
2053 if (target && target->ToPlayer())
2054 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2055 }
2056 return;
2057 default:
2058 break;
2059 }
2060
2061 // select spell implicit targets based on effect type
2062 if (!m_spellInfo->Effects[effIndex].GetImplicitTargetType())
2063 return;
2064
2065 uint32 targetMask = m_spellInfo->Effects[effIndex].GetMissingTargetMask();
2066
2067 if (!targetMask)
2068 return;
2069
2070 WorldObject* target = nullptr;
2071
2072 switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType())
2073 {
2074 // add explicit object target or self to the target map
2076 // player which not released his spirit is Unit, but target flag for it is TARGET_FLAG_CORPSE_MASK
2078 {
2080 target = unitTarget;
2081 else if (targetMask & TARGET_FLAG_CORPSE_MASK)
2082 {
2083 if (Corpse* corpseTarget = m_targets.GetCorpseTarget())
2084 {
2086 if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()))
2087 target = owner;
2088 }
2089 }
2090 else //if (targetMask & TARGET_FLAG_UNIT_MASK)
2091 target = m_caster;
2092 }
2093 if (targetMask & TARGET_FLAG_ITEM_MASK)
2094 {
2096 AddItemTarget(itemTarget, 1 << effIndex);
2097 return;
2098 }
2099 if (targetMask & TARGET_FLAG_GAMEOBJECT_MASK)
2100 target = m_targets.GetGOTarget();
2101 break;
2102 // add self to the target map
2104 if (targetMask & TARGET_FLAG_UNIT_MASK)
2105 target = m_caster;
2106 break;
2107 default:
2108 break;
2109 }
2110
2112
2113 if (target)
2114 {
2115 if (target->ToUnit())
2116 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2117 else if (target->ToGameObject())
2118 AddGOTarget(target->ToGameObject(), 1 << effIndex);
2119 }
2120}
@ EFFECT_IMPLICIT_TARGET_CASTER
Definition SpellInfo.h:145
@ EFFECT_IMPLICIT_TARGET_EXPLICIT
Definition SpellInfo.h:144
@ TARGET_FLAG_ITEM_MASK
Definition SpellInfo.h:73
GameObject * ToGameObject()
Definition Object.h:214
Corpse * GetCorpseTarget() const
Definition Spell.cpp:294
Definition SpellInfo.h:218
void AddGOTarget(GameObject *target, uint32 effectMask)
Definition Spell.cpp:2515
void AddUnitTarget(Unit *target, uint32 effectMask, bool checkIfValid=true, bool implicit=true)
Definition Spell.cpp:2382
void AddItemTarget(Item *item, uint32 effectMask)
Definition Spell.cpp:2577
void CallScriptObjectTargetSelectHandlers(WorldObject *&target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:8738

References AddGOTarget(), AddItemTarget(), AddUnitTarget(), CallScriptObjectTargetSelectHandlers(), EFFECT_IMPLICIT_TARGET_CASTER, EFFECT_IMPLICIT_TARGET_EXPLICIT, SpellInfo::Effects, ObjectAccessor::FindPlayer(), SpellCastTargets::GetCorpseTarget(), SpellCastTargets::GetGOTarget(), SpellCastTargets::GetItemTarget(), Unit::GetTarget(), SpellCastTargets::GetUnitTarget(), Object::IsPlayer(), itemTarget, m_caster, m_spellInfo, m_targets, SPELL_EFFECT_SUMMON_PLAYER, SPELL_EFFECT_SUMMON_RAF_FRIEND, TARGET_FLAG_CORPSE_MASK, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_ITEM_MASK, TARGET_FLAG_UNIT_MASK, Object::ToGameObject(), Object::ToPlayer(), Object::ToUnit(), and unitTarget.

Referenced by SelectSpellTargets().

◆ SelectExplicitTargets()

void Spell::SelectExplicitTargets ( )
787{
788 // here go all explicit target changes made to explicit targets after spell prepare phase is finished
789 if (Unit* target = m_targets.GetUnitTarget())
790 {
791 // check for explicit target redirection, for Grounding Totem for example
795 {
796 Unit* redirect;
797 switch (m_spellInfo->DmgClass)
798 {
801 break;
805 break;
806 default:
807 redirect = nullptr;
808 break;
809 }
810 if (redirect && (redirect != target))
811 {
812 m_targets.SetUnitTarget(redirect);
814 }
815 }
816 }
817}
Unit * GetMeleeHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo=nullptr)
Definition Unit.cpp:11152
Unit * GetMagicHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo)
Definition Unit.cpp:11114

References SpellInfo::DmgClass, SpellInfo::GetExplicitTargetMask(), Unit::GetMagicHitRedirectTarget(), Unit::GetMeleeHitRedirectTarget(), SpellCastTargets::GetUnitTarget(), SpellInfo::HasEffect(), Unit::IsFriendlyTo(), SpellInfo::IsPositive(), m_caster, m_spellFlags, m_spellInfo, m_targets, SpellCastTargets::SetUnitTarget(), SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_DISPEL, SPELL_FLAG_REDIRECTED, TARGET_FLAG_UNIT, and TARGET_FLAG_UNIT_ENEMY.

Referenced by SelectSpellTargets().

◆ SelectImplicitAreaTargets()

void Spell::SelectImplicitAreaTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1265{
1266 Unit* referer = nullptr;
1267 switch (targetType.GetReferenceType())
1268 {
1272 referer = m_caster;
1273 break;
1275 referer = m_targets.GetUnitTarget();
1276 break;
1278 {
1279 // find last added target for this effect
1280 for (std::list<TargetInfo>::reverse_iterator ihit = m_UniqueTargetInfo.rbegin(); ihit != m_UniqueTargetInfo.rend(); ++ihit)
1281 {
1282 if (ihit->effectMask & (1 << effIndex))
1283 {
1284 referer = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
1285 break;
1286 }
1287 }
1288 break;
1289 }
1290 default:
1291 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1292 return;
1293 }
1294 if (!referer)
1295 return;
1296
1297 Position const* center = nullptr;
1298 switch (targetType.GetReferenceType())
1299 {
1301 center = m_targets.GetSrcPos();
1302 break;
1304 center = m_targets.GetDstPos();
1305 break;
1309 center = referer;
1310 break;
1311 default:
1312 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1313 return;
1314 }
1315
1316 // Xinef: the distance should be increased by caster size, it is neglected in latter calculations
1317 std::list<WorldObject*> targets;
1318 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1319 SearchAreaTargets(targets, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
1320
1321 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1322
1323 if (!targets.empty())
1324 {
1325 // Other special target selection goes here
1326 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1327 {
1329 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
1330 if ((*j)->IsAffectedOnSpell(m_spellInfo))
1331 maxTargets += (*j)->GetAmount();
1332
1333 Acore::Containers::RandomResize(targets, maxTargets);
1334 }
1335
1336 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1337 {
1338 if (Unit* unitTarget = (*itr)->ToUnit())
1339 AddUnitTarget(unitTarget, effMask, false);
1340 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1341 AddGOTarget(gObjTarget, effMask);
1342 }
1343 }
1344}
@ SPELL_AURA_MOD_MAX_AFFECTED_TARGETS
Definition SpellAuraDefines.h:340
@ TARGET_REFERENCE_TYPE_SRC
Definition SpellInfo.h:93
@ TARGET_REFERENCE_TYPE_LAST
Definition SpellInfo.h:92
Position const * GetSrcPos() const
Definition Spell.cpp:362
void CallScriptObjectAreaTargetSelectHandlers(std::list< WorldObject * > &targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:8724
void RandomResize(C &container, std::size_t requestedSize)
Definition Containers.h:79
float RadiusMod
Definition Spell.h:224
uint32 MaxAffectedTargets
Definition Spell.h:223

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, Unit::GetAuraEffectsByType(), SpellImplicitTargetInfo::GetCheckType(), SpellCastTargets::GetDstPos(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellCastTargets::GetSrcPos(), ObjectAccessor::GetUnit(), SpellCastTargets::GetUnitTarget(), m_caster, m_spellInfo, m_spellValue, m_targets, m_UniqueTargetInfo, SpellValue::MaxAffectedTargets, SpellValue::RadiusMod, Acore::Containers::RandomResize(), SearchAreaTargets(), SPELL_AURA_MOD_MAX_AFFECTED_TARGETS, TARGET_REFERENCE_TYPE_CASTER, TARGET_REFERENCE_TYPE_DEST, TARGET_REFERENCE_TYPE_LAST, TARGET_REFERENCE_TYPE_SRC, TARGET_REFERENCE_TYPE_TARGET, Object::ToGameObject(), Object::ToUnit(), and unitTarget.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitCasterDestTargets()

void Spell::SelectImplicitCasterDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
Todo:
fix this check
1347{
1349
1350 switch (targetType.GetTarget())
1351 {
1352 case TARGET_DEST_CASTER:
1354 break;
1355 case TARGET_DEST_HOME:
1356 if (Player* playerCaster = m_caster->ToPlayer())
1357 dest = SpellDestination(playerCaster->m_homebindX, playerCaster->m_homebindY, playerCaster->m_homebindZ, playerCaster->GetOrientation(), playerCaster->m_homebindMapId);
1358 break;
1359 case TARGET_DEST_DB:
1360 if (SpellTargetPosition const* st = sSpellMgr->GetSpellTargetPosition(m_spellInfo->Id, effIndex))
1361 {
1364 dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation, (int32)st->target_mapId);
1365 else if (st->target_mapId == m_caster->GetMapId())
1366 dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation);
1367 }
1368 else
1369 {
1370 LOG_DEBUG("spells.aura", "SPELL: unknown target coordinates for spell ID {}", m_spellInfo->Id);
1371 if (WorldObject* target = m_targets.GetObjectTarget())
1372 dest = SpellDestination(*target);
1373 }
1374 break;
1376 {
1377 float min_dis = m_spellInfo->GetMinRange(true);
1378 float max_dis = m_spellInfo->GetMaxRange(true);
1379 float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
1380 float x, y, z, angle;
1381 angle = (float)rand_norm() * static_cast<float>(M_PI * 35.0f / 180.0f) - static_cast<float>(M_PI * 17.5f / 180.0f);
1382 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dis, angle); this contains extra code that breaks fishing
1384
1385 float ground = m_caster->GetMapHeight(x, y, z, true);
1386 float liquidLevel = VMAP_INVALID_HEIGHT_VALUE;
1388 if (liquidData.Status)
1389 liquidLevel = liquidData.Level;
1390
1391 if (liquidLevel <= ground) // When there is no liquid Map::GetWaterOrGroundLevel returns ground level
1392 {
1395 finish(false);
1396 return;
1397 }
1398
1399 if (ground + 0.75 > liquidLevel)
1400 {
1403 finish(false);
1404 return;
1405 }
1406
1407 if (!m_caster->IsWithinLOS(x, y, z))
1408 {
1411 finish(false);
1412 return;
1413 }
1414
1415 dest = SpellDestination(x, y, liquidLevel, m_caster->GetOrientation());
1416 break;
1417 }
1419 {
1420 float distance = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1421 Map* map = m_caster->GetMap();
1422 uint32 mapid = m_caster->GetMapId();
1423 uint32 phasemask = m_caster->GetPhaseMask();
1424 float collisionHeight = m_caster->GetCollisionHeight();
1425 float destz = 0.0f, startx = 0.0f, starty = 0.0f, startz = 0.0f, starto = 0.0f;
1426
1427 Position pos;
1428 Position lastpos;
1429 m_caster->GetPosition(startx, starty, startz, starto);
1430 pos.Relocate(startx, starty, startz, starto);
1431 float destx = pos.GetPositionX() + distance * cos(pos.GetOrientation());
1432 float desty = pos.GetPositionY() + distance * sin(pos.GetOrientation());
1433
1434 // Added GROUND_HEIGHT_TOLERANCE to account for cases where, during a jump,
1435 // the Z position may be slightly below the vmap ground level.
1436 // Without this tolerance, a ray trace might incorrectly attempt to find ground
1437 // beneath the actual surface.
1438 //
1439 // Example:
1440 // actual vmap ground: -56.342392
1441 // Z position: -56.347195
1442 float searchGroundZPos = pos.GetPositionZ()+GROUND_HEIGHT_TOLERANCE;
1443 float ground = map->GetHeight(phasemask, pos.GetPositionX(), pos.GetPositionY(), searchGroundZPos);
1444
1445 bool isCasterInWater = m_caster->IsInWater();
1446 if (!m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING) || (pos.GetPositionZ() - ground < distance))
1447 {
1448 float tstX = 0.0f, tstY = 0.0f, tstZ = 0.0f, prevX = 0.0f, prevY = 0.0f, prevZ = 0.0f;
1449 float tstZ1 = 0.0f, tstZ2 = 0.0f, tstZ3 = 0.0f, destz1 = 0.0f, destz2 = 0.0f, destz3 = 0.0f, srange = 0.0f, srange1 = 0.0f, srange2 = 0.0f, srange3 = 0.0f;
1450 float maxtravelDistZ = 2.65f;
1451 float overdistance = 0.0f;
1452 float totalpath = 0.0f;
1453 float beforewaterz = 0.0f;
1454 bool inwater = false;
1455 bool wcol = false;
1456 const float step = 2.0f;
1457 const uint8 numChecks = std::ceil(std::fabs(distance / step));
1458 const float DELTA_X = (destx - pos.GetPositionX()) / numChecks;
1459 const float DELTA_Y = (desty - pos.GetPositionY()) / numChecks;
1460 int j = 1;
1461 for (; j < (numChecks + 1); j++)
1462 {
1463 prevX = pos.GetPositionX() + (float(j - 1) * DELTA_X);
1464 prevY = pos.GetPositionY() + (float(j - 1) * DELTA_Y);
1465 tstX = pos.GetPositionX() + (float(j) * DELTA_X);
1466 tstY = pos.GetPositionY() + (float(j) * DELTA_Y);
1467
1468 if (j < 2)
1469 {
1470 prevZ = pos.GetPositionZ();
1471 }
1472 else
1473 {
1474 prevZ = tstZ;
1475 }
1476
1477 tstZ = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true);
1478 ground = tstZ;
1479
1480 if (!isCasterInWater)
1481 {
1482 if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1483 {
1484 if (!(beforewaterz != 0.0f))
1485 {
1486 beforewaterz = prevZ;
1487 }
1488 tstZ = beforewaterz;
1489 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1490 //LOG_ERROR("spells", "(start was from land) step in water , number of cycle = {} , distance of step = {}, total path = {}, Z = {}", j, srange, totalpath, tstZ);
1491 }
1492 }
1493 else if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1494 {
1495 prevZ = pos.GetPositionZ();
1496 tstZ = pos.GetPositionZ();
1497 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1498
1499 inwater = true;
1500 if (inwater && (fabs(tstZ - ground) < 2.0f))
1501 {
1502 wcol = true;
1503 //LOG_ERROR("spells", "step in water with collide and use standart check (for continue way after possible collide), number of cycle = {} ", j);
1504 }
1505
1506 // if (j < 2)
1507 // LOG_ERROR("spells", "(start in water) step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1508 // else
1509 // LOG_ERROR("spells", "step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1510 }
1511
1512 bool IsInWater = map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight);
1513 if ((!IsInWater && tstZ != beforewaterz) || wcol) // second safety check z for blink way if on the ground
1514 {
1515 if (inwater && !IsInWater)
1516 inwater = false;
1517
1518 // highest available point
1519 tstZ1 = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true, 25.0f);
1520 // upper or floor
1521 tstZ2 = map->GetHeight(phasemask, tstX, tstY, prevZ, true, 25.0f);
1522 //lower than floor
1523 tstZ3 = map->GetHeight(phasemask, tstX, tstY, prevZ - maxtravelDistZ / 2, true, 25.0f);
1524
1525 //distance of rays, will select the shortest in 3D
1526 srange1 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ1 - prevZ) * (tstZ1 - prevZ));
1527 //LOG_ERROR("spells", "step = {}, distance of ray1 = {}", j, srange1);
1528 srange2 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ2 - prevZ) * (tstZ2 - prevZ));
1529 //LOG_ERROR("spells", "step = {}, distance of ray2 = {}", j, srange2);
1530 srange3 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ3 - prevZ) * (tstZ3 - prevZ));
1531 //LOG_ERROR("spells", "step = {}, distance of ray3 = {}", j, srange3);
1532
1533 if (srange1 < srange2)
1534 {
1535 tstZ = tstZ1;
1536 srange = srange1;
1537 }
1538 else if (srange3 < srange2)
1539 {
1540 tstZ = tstZ3;
1541 srange = srange3;
1542 }
1543 else
1544 {
1545 tstZ = tstZ2;
1546 srange = srange2;
1547 }
1548
1549 //LOG_ERROR("spells", "step on ground, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1550 }
1551
1552 destx = tstX;
1553 desty = tstY;
1554 destz = tstZ;
1555
1556 totalpath += srange;
1557
1558 if (totalpath > distance)
1559 {
1560 overdistance = totalpath - distance;
1561 //LOG_ERROR("spells", "total path > than distance in 3D , need to move back a bit for save distance, total path = {}, overdistance = {}", totalpath, overdistance);
1562 }
1563
1564 bool col = VMAP::VMapFactory::createOrGetVMapMgr()->GetObjectHitPos(mapid, prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1565 // check dynamic collision
1566 bool dcol = m_caster->GetMap()->GetObjectHitPos(phasemask, prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1567
1568 // collision occured
1569 if (col || dcol || (overdistance > 0.0f && !map->IsInWater(phasemask, tstX, tstY, ground, collisionHeight)) || (fabs(prevZ - tstZ) > maxtravelDistZ && (tstZ > prevZ)))
1570 {
1571 if ((overdistance > 0.0f) && (overdistance < 1.f))
1572 {
1573 destx = prevX + overdistance * cos(pos.GetOrientation());
1574 desty = prevY + overdistance * sin(pos.GetOrientation());
1575 //LOG_ERROR("spells", "(collision) collision occured 1");
1576 }
1577 else
1578 {
1579 // move back a bit
1580 destx = tstX - (0.6 * cos(pos.GetOrientation()));
1581 desty = tstY - (0.6 * sin(pos.GetOrientation()));
1582 //LOG_ERROR("spells", "(collision) collision occured 2");
1583 }
1584
1585 // highest available point
1586 destz1 = map->GetHeight(phasemask, destx, desty, prevZ + maxtravelDistZ, true, 25.0f);
1587 // upper or floor
1588 destz2 = map->GetHeight(phasemask, destx, desty, prevZ, true, 25.0f);
1589 //lower than floor
1590 destz3 = map->GetHeight(phasemask, destx, desty, prevZ - maxtravelDistZ / 2, true, 25.0f);
1591
1592 //distance of rays, will select the shortest in 3D
1593 srange1 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz1 - prevZ) * (destz1 - prevZ));
1594 srange2 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz2 - prevZ) * (destz2 - prevZ));
1595 srange3 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz3 - prevZ) * (destz3 - prevZ));
1596
1597 if (srange1 < srange2)
1598 destz = destz1;
1599 else if (srange3 < srange2)
1600 destz = destz3;
1601 else
1602 destz = destz2;
1603
1604 if (inwater && destz < prevZ && !wcol)
1605 destz = prevZ;
1606 //LOG_ERROR("spells", "(collision) destZ rewrited in prevZ");
1607
1608 // Don't make the player move backward from the xy adjustments by collisions.
1609 if ((DELTA_X > 0 && startx > destx) || (DELTA_X < 0 && startx < destx) ||
1610 (DELTA_Y > 0 && starty > desty) || (DELTA_Y < 0 && starty < desty))
1611 {
1612 destx = startx;
1613 desty = starty;
1614 destz = startz;
1615 }
1616
1617 break;
1618 }
1619 // we have correct destz now
1620 }
1621
1622 lastpos.Relocate(destx, desty, destz, pos.GetOrientation());
1623 dest = SpellDestination(lastpos);
1624 }
1625 else
1626 {
1627 float z = pos.GetPositionZ();
1628 bool col = VMAP::VMapFactory::createOrGetVMapMgr()->GetObjectHitPos(mapid, pos.GetPositionX(), pos.GetPositionY(), z, destx, desty, z, destx, desty, z, -0.5f);
1629 // check dynamic collision
1630 bool dcol = m_caster->GetMap()->GetObjectHitPos(phasemask, pos.GetPositionX(), pos.GetPositionY(), z, destx, desty, z, destx, desty, z, -0.5f);
1631
1632 // collision occured
1633 if (col || dcol)
1634 {
1635 // move back a bit
1636 destx = destx - (0.6 * cos(pos.GetOrientation()));
1637 desty = desty - (0.6 * sin(pos.GetOrientation()));
1638 }
1639
1640 lastpos.Relocate(destx, desty, z, pos.GetOrientation());
1641 dest = SpellDestination(lastpos);
1642 //float range = sqrt((desty - pos.GetPositionY())*(desty - pos.GetPositionY()) + (destx - pos.GetPositionX())*(destx - pos.GetPositionX()));
1643 //LOG_ERROR("spells", "Blink number 2, in falling but at a hight, distance of blink = {}", range);
1644 }
1645 break;
1646 }
1647 default:
1648 {
1649 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1650 float angle = targetType.CalcDirectionAngle();
1651 float objSize = m_caster->GetCombatReach();
1652
1653 switch (targetType.GetTarget())
1654 {
1656 dist = PET_FOLLOW_DIST;
1657 break;
1659 if (dist > objSize)
1660 dist = objSize + (dist - objSize) * float(rand_norm());
1661 break;
1666 {
1667 static float const DefaultTotemDistance = 3.0f;
1668 if (!m_spellInfo->Effects[effIndex].HasRadius())
1669 dist = DefaultTotemDistance;
1670 break;
1671 }
1672 default:
1673 break;
1674 }
1675
1676 if (dist < objSize)
1677 {
1678 dist = objSize;
1679 }
1680
1681 Position pos = dest._position;
1682 m_caster->MovePositionToFirstCollision(pos, dist, angle);
1683
1684 dest.Relocate(pos);
1685 break;
1686 }
1687 }
1688
1689 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1690 m_targets.SetDst(dest);
1691}
#define MAP_ALL_LIQUIDS
Definition GridTerrainData.h:40
#define VMAP_INVALID_HEIGHT_VALUE
Definition IVMapMgr.h:49
@ SPELL_EFFECT_BIND
Definition SharedDefines.h:800
@ SPELL_EFFECT_TELEPORT_UNITS
Definition SharedDefines.h:794
@ TARGET_DEST_CASTER_RANDOM
Definition SharedDefines.h:1487
@ TARGET_DEST_DB
Definition SharedDefines.h:1433
@ TARGET_DEST_CASTER_FRONT_LEAP
Definition SharedDefines.h:1470
@ TARGET_DEST_CASTER_FRONT_LEFT
Definition SharedDefines.h:1459
@ TARGET_DEST_CASTER_BACK_RIGHT
Definition SharedDefines.h:1457
@ TARGET_DEST_CASTER_FISHING
Definition SharedDefines.h:1454
@ TARGET_DEST_CASTER_BACK_LEFT
Definition SharedDefines.h:1458
@ TARGET_DEST_CASTER_SUMMON
Definition SharedDefines.h:1447
@ TARGET_DEST_CASTER
Definition SharedDefines.h:1434
@ TARGET_DEST_CASTER_FRONT_RIGHT
Definition SharedDefines.h:1456
@ TARGET_DEST_CASTER_36
Definition SharedDefines.h:1451
@ TARGET_DEST_HOME
Definition SharedDefines.h:1429
float const GROUND_HEIGHT_TOLERANCE
Definition SharedDefines.h:26
@ SPELL_FAILED_TOO_SHALLOW
Definition SharedDefines.h:1116
@ MOVEMENTFLAG_FALLING
Definition UnitDefines.h:379
float GetHeight(float x, float y, float z, bool checkVMap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH) const
Definition Map.cpp:1141
LiquidData const GetLiquidData(uint32 phaseMask, float x, float y, float z, float collisionHeight, uint8 ReqLiquidType)
Definition Map.cpp:1302
bool IsInWater(uint32 phaseMask, float x, float y, float z, float collisionHeight) const
Definition Map.cpp:1601
bool GetObjectHitPos(uint32 phasemask, float x1, float y1, float z1, float x2, float y2, float z2, float &rx, float &ry, float &rz, float modifyDist)
Definition Map.cpp:1579
void CallScriptDestinationTargetSelectHandlers(SpellDestination &target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:8752
float GetCollisionHeight() const override
Return collision height sent to client.
Definition Unit.cpp:20966
static VMapMgr2 * createOrGetVMapMgr()
Definition VMapFactory.cpp:27
bool GetObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float &rx, float &ry, float &rz, float modifyDist) override
Definition VMapMgr2.cpp:201
float GetMapHeight(float x, float y, float z, bool vmap=true, float distanceToSearch=50.0f) const
Definition Object.cpp:3012
void GetNearPoint(WorldObject const *searcher, float &x, float &y, float &z, float searcher_size, float distance2d, float absAngle, float controlZ=0, Position const *startPos=nullptr) const
Definition Object.cpp:2619
Definition GridTerrainData.h:199
float Level
Definition GridTerrainData.h:204
LiquidStatus Status
Definition GridTerrainData.h:206
Definition SpellMgr.h:396

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), VMAP::VMapFactory::createOrGetVMapMgr(), DEFAULT_WORLD_OBJECT_SIZE, SpellInfo::Effects, finish(), Unit::GetCollisionHeight(), Unit::GetCombatReach(), Map::GetHeight(), Map::GetLiquidData(), WorldObject::GetMap(), WorldObject::GetMapHeight(), WorldLocation::GetMapId(), SpellInfo::GetMaxRange(), SpellInfo::GetMinRange(), WorldObject::GetNearPoint(), Map::GetObjectHitPos(), VMAP::VMapMgr2::GetObjectHitPos(), SpellCastTargets::GetObjectTarget(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), SpellImplicitTargetInfo::GetTarget(), GROUND_HEIGHT_TOLERANCE, SpellInfo::HasEffect(), Unit::HasUnitMovementFlag(), SpellInfo::Id, Unit::IsInWater(), Map::IsInWater(), WorldObject::IsWithinLOS(), LiquidData::Level, LOG_DEBUG, m_caster, m_spellInfo, m_targets, MAP_ALL_LIQUIDS, MOVEMENTFLAG_FALLING, WorldObject::MovePositionToFirstCollision(), PET_FOLLOW_DIST, rand_norm(), Position::Relocate(), SpellDestination::Relocate(), SendCastResult(), SendChannelUpdate(), SpellCastTargets::SetDst(), SPELL_EFFECT_BIND, SPELL_EFFECT_TELEPORT_UNITS, SPELL_FAILED_LINE_OF_SIGHT, SPELL_FAILED_NOT_HERE, SPELL_FAILED_TOO_SHALLOW, sSpellMgr, LiquidData::Status, TARGET_DEST_CASTER, TARGET_DEST_CASTER_36, TARGET_DEST_CASTER_BACK_LEFT, TARGET_DEST_CASTER_BACK_RIGHT, TARGET_DEST_CASTER_FISHING, TARGET_DEST_CASTER_FRONT_LEAP, TARGET_DEST_CASTER_FRONT_LEFT, TARGET_DEST_CASTER_FRONT_RIGHT, TARGET_DEST_CASTER_RANDOM, TARGET_DEST_CASTER_SUMMON, TARGET_DEST_DB, TARGET_DEST_HOME, Object::ToPlayer(), and VMAP_INVALID_HEIGHT_VALUE.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitCasterObjectTargets()

void Spell::SelectImplicitCasterObjectTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1770{
1771 WorldObject* target = nullptr;
1772 bool checkIfValid = true;
1773
1774 switch (targetType.GetTarget())
1775 {
1776 case TARGET_UNIT_CASTER:
1777 target = m_caster;
1778 checkIfValid = false;
1779 break;
1780 case TARGET_UNIT_MASTER:
1781 target = m_caster->GetCharmerOrOwner();
1782 break;
1783 case TARGET_UNIT_PET:
1784 target = m_caster->GetGuardianPet();
1785 if (!target)
1786 target = m_caster->GetCharm();
1787 break;
1789 if (m_caster->IsSummon())
1790 target = m_caster->ToTempSummon()->GetSummonerUnit();
1791 break;
1793 target = m_caster->GetVehicleBase();
1794 break;
1804 target = m_caster->GetVehicleKit()->GetPassenger(targetType.GetTarget() - TARGET_UNIT_PASSENGER_0);
1805 break;
1806 default:
1807 break;
1808 }
1809
1810 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1811
1812 if (target && target->ToUnit())
1813 AddUnitTarget(target->ToUnit(), 1 << effIndex, checkIfValid);
1814}
@ TARGET_UNIT_PASSENGER_1
Definition SharedDefines.h:1512
@ TARGET_UNIT_PASSENGER_6
Definition SharedDefines.h:1517
@ TARGET_UNIT_VEHICLE
Definition SharedDefines.h:1509
@ TARGET_UNIT_PASSENGER_2
Definition SharedDefines.h:1513
@ TARGET_UNIT_PASSENGER_4
Definition SharedDefines.h:1515
@ TARGET_UNIT_PASSENGER_7
Definition SharedDefines.h:1518
@ TARGET_UNIT_MASTER
Definition SharedDefines.h:1442
@ TARGET_UNIT_PASSENGER_5
Definition SharedDefines.h:1516
@ TARGET_UNIT_PASSENGER_3
Definition SharedDefines.h:1514
@ TARGET_UNIT_SUMMONER
Definition SharedDefines.h:1507
@ TARGET_UNIT_PASSENGER_0
Definition SharedDefines.h:1511
Unit * GetSummonerUnit() const
Definition TemporarySummon.cpp:44
Unit * GetVehicleBase() const
Definition Unit.cpp:18839
Unit * GetPassenger(int8 seatId) const
Definition Vehicle.cpp:228

References AddUnitTarget(), CallScriptObjectTargetSelectHandlers(), Unit::GetCharm(), Unit::GetCharmerOrOwner(), Unit::GetGuardianPet(), Vehicle::GetPassenger(), TempSummon::GetSummonerUnit(), SpellImplicitTargetInfo::GetTarget(), Unit::GetVehicleBase(), Unit::GetVehicleKit(), Object::IsCreature(), Unit::IsSummon(), Unit::IsVehicle(), m_caster, TARGET_UNIT_CASTER, TARGET_UNIT_MASTER, TARGET_UNIT_PASSENGER_0, TARGET_UNIT_PASSENGER_1, TARGET_UNIT_PASSENGER_2, TARGET_UNIT_PASSENGER_3, TARGET_UNIT_PASSENGER_4, TARGET_UNIT_PASSENGER_5, TARGET_UNIT_PASSENGER_6, TARGET_UNIT_PASSENGER_7, TARGET_UNIT_PET, TARGET_UNIT_SUMMONER, TARGET_UNIT_VEHICLE, Object::ToCreature(), Unit::ToTempSummon(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitChainTargets()

void Spell::SelectImplicitChainTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
WorldObject target,
uint32  effMask 
)
1839{
1840 uint32 maxTargets = m_spellInfo->Effects[effIndex].ChainTarget;
1841 if (Player* modOwner = m_caster->GetSpellModOwner())
1842 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, maxTargets, this);
1843
1844 if (maxTargets > 1)
1845 {
1846 // mark damage multipliers as used
1847 for (uint32 k = effIndex; k < MAX_SPELL_EFFECTS; ++k)
1848 if (effMask & (1 << k))
1849 m_damageMultipliers[k] = 1.0f;
1850 m_applyMultiplierMask |= effMask;
1851
1852 std::list<WorldObject*> targets;
1853 SearchChainTargets(targets, maxTargets - 1, target, targetType.GetObjectType(), targetType.GetCheckType(), targetType.GetSelectionCategory()
1854 , m_spellInfo->Effects[effIndex].ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY);
1855
1856 // Chain primary target is added earlier
1857 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1858
1859 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1860 if (Unit* unitTarget = (*itr)->ToUnit())
1861 AddUnitTarget(unitTarget, effMask, false);
1862 }
1863}
@ TARGET_UNIT_TARGET_CHAINHEAL_ALLY
Definition SharedDefines.h:1460
@ SPELLMOD_JUMP_TARGETS
Definition SpellDefines.h:93
void SearchChainTargets(std::list< WorldObject * > &targets, uint32 chainTargets, WorldObject *target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, SpellTargetSelectionCategories selectCategory, std::shared_ptr< ConditionList > condList, bool isChainHeal)
Definition Spell.cpp:2195

References AddUnitTarget(), CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, SpellImplicitTargetInfo::GetCheckType(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetSelectionCategory(), Unit::GetSpellModOwner(), SpellImplicitTargetInfo::GetTarget(), SpellInfo::Id, m_applyMultiplierMask, m_caster, m_damageMultipliers, m_spellInfo, MAX_SPELL_EFFECTS, SearchChainTargets(), SPELLMOD_JUMP_TARGETS, TARGET_UNIT_TARGET_CHAINHEAL_ALLY, Object::ToUnit(), and unitTarget.

Referenced by SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ SelectImplicitChannelTargets()

void Spell::SelectImplicitChannelTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1045{
1046 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1047 {
1048 ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target reference type");
1049 return;
1050 }
1051
1052 switch (targetType.GetTarget())
1053 {
1055 {
1056 // Xinef: All channel selectors have needed data passed in m_targets structure
1058 if (target)
1059 {
1060 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1061 // unit target may be no longer avalible - teleported out of map for example
1062 if (target && target->ToUnit())
1063 AddUnitTarget(target->ToUnit(), 1 << effIndex);
1064 }
1065 else
1066 {
1067 LOG_DEBUG("spells.aura", "SPELL: cannot find channel spell target for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1068 }
1069 break;
1070 }
1075 {
1076 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1077 if (target)
1078 m_targets.SetDst(*target);
1079 }
1081 {
1082 if (channeledSpell->m_targets.GetUnitTarget())
1083 m_targets.SetDst(*channeledSpell->m_targets.GetUnitTarget());
1084 }
1085 else //if (!m_targets.HasDst())
1086 {
1087 LOG_DEBUG("spells.aura", "SPELL: cannot find channel spell destination for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1088 }
1089 break;
1091 if (GetOriginalCaster())
1093 break;
1094 default:
1095 ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target type");
1096 break;
1097 }
1098}
@ TARGET_DEST_CHANNEL_TARGET
Definition SharedDefines.h:1491
@ TARGET_UNIT_CHANNEL_TARGET
Definition SharedDefines.h:1492
@ TARGET_DEST_CHANNEL_CASTER
Definition SharedDefines.h:1521
WorldObject * GetObjectTargetChannel(Unit *caster) const
Definition Spell.cpp:464
SpellDestination const * GetDstChannel() const
Definition Spell.cpp:474
bool HasDstChannel() const
Definition Spell.cpp:469

References AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), CURRENT_CHANNELED_SPELL, Unit::GetCurrentSpell(), SpellCastTargets::GetDstChannel(), SpellCastTargets::GetObjectTargetChannel(), GetOriginalCaster(), SpellImplicitTargetInfo::GetReferenceType(), SpellImplicitTargetInfo::GetTarget(), SpellCastTargets::HasDstChannel(), SpellInfo::Id, LOG_DEBUG, m_caster, m_originalCaster, m_spellInfo, m_targets, SpellCastTargets::SetDst(), TARGET_DEST_CHANNEL_CASTER, TARGET_DEST_CHANNEL_TARGET, TARGET_REFERENCE_TYPE_CASTER, TARGET_UNIT_CHANNEL_TARGET, and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitConeTargets()

void Spell::SelectImplicitConeTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1215{
1216 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1217 {
1218 ASSERT(false && "Spell::SelectImplicitConeTargets: received not implemented target reference type");
1219 return;
1220 }
1221 std::list<WorldObject*> targets;
1222 SpellTargetObjectTypes objectType = targetType.GetObjectType();
1223 SpellTargetCheckTypes selectionType = targetType.GetCheckType();
1224 std::shared_ptr<ConditionList> condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1225 float coneAngle = M_PI / 2;
1226 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1227
1228 if (uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList))
1229 {
1230 Acore::WorldObjectSpellConeTargetCheck check(coneAngle, radius, m_caster, m_spellInfo, selectionType, condList);
1231 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
1232 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> >(searcher, containerTypeMask, m_caster, m_caster, radius);
1233
1234 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1235
1236 if (!targets.empty())
1237 {
1238 // Other special target selection goes here
1239 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1240 {
1242 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
1243 if ((*j)->IsAffectedOnSpell(m_spellInfo))
1244 maxTargets += (*j)->GetAmount();
1245
1246 Acore::Containers::RandomResize(targets, maxTargets);
1247 }
1248
1249 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1250 {
1251 if (Unit* unit = (*itr)->ToUnit())
1252 {
1253 AddUnitTarget(unit, effMask, false);
1254 }
1255 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1256 {
1257 AddGOTarget(gObjTarget, effMask);
1258 }
1259 }
1260 }
1261 }
1262}
SpellTargetCheckTypes
Definition SpellInfo.h:114
SpellTargetObjectTypes
Definition SpellInfo.h:98

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, Unit::GetAuraEffectsByType(), SpellImplicitTargetInfo::GetCheckType(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), GetSearcherTypeMask(), m_caster, m_spellInfo, m_spellValue, SpellValue::MaxAffectedTargets, SpellValue::RadiusMod, Acore::Containers::RandomResize(), SPELL_AURA_MOD_MAX_AFFECTED_TARGETS, TARGET_REFERENCE_TYPE_CASTER, Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitDestDestTargets()

void Spell::SelectImplicitDestDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1731{
1732 // set destination to caster if no dest provided
1733 // can only happen if previous destination target could not be set for some reason
1734 // (not found nearby target, or channel target for example
1735 // maybe we should abort the spell in such case?
1736 CheckDst();
1737
1739
1740 switch (targetType.GetTarget())
1741 {
1745 case TARGET_DEST_DEST:
1746 return;
1747 case TARGET_DEST_TRAJ:
1748 SelectImplicitTrajTargets(effIndex, targetType);
1749 return;
1750 default:
1751 {
1752 float angle = targetType.CalcDirectionAngle();
1753 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1754 if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
1755 dist *= float(rand_norm());
1756
1757 Position pos = dest._position;
1758 m_caster->MovePosition(pos, dist, angle);
1759
1760 dest.Relocate(pos);
1761 break;
1762 }
1763 }
1764
1765 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1766 m_targets.ModDst(dest);
1767}
@ TARGET_DEST_DYNOBJ_ENEMY
Definition SharedDefines.h:1443
@ TARGET_DEST_DEST_RANDOM
Definition SharedDefines.h:1501
@ TARGET_DEST_DEST
Definition SharedDefines.h:1502
@ TARGET_DEST_DYNOBJ_NONE
Definition SharedDefines.h:1503
@ TARGET_DEST_DYNOBJ_ALLY
Definition SharedDefines.h:1444
@ TARGET_DEST_TRAJ
Definition SharedDefines.h:1504
void ModDst(Position const &pos)
Definition Spell.cpp:436
SpellDestination const * GetDst() const
Definition Spell.cpp:396
void MovePosition(Position &pos, float dist, float angle)
Definition Object.cpp:2769

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), CheckDst(), SpellInfo::Effects, SpellCastTargets::GetDst(), SpellImplicitTargetInfo::GetTarget(), m_caster, m_spellInfo, m_targets, SpellCastTargets::ModDst(), WorldObject::MovePosition(), rand_norm(), SpellDestination::Relocate(), SelectImplicitTrajTargets(), TARGET_DEST_DEST, TARGET_DEST_DEST_RANDOM, TARGET_DEST_DYNOBJ_ALLY, TARGET_DEST_DYNOBJ_ENEMY, TARGET_DEST_DYNOBJ_NONE, and TARGET_DEST_TRAJ.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitNearbyTargets()

void Spell::SelectImplicitNearbyTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1101{
1102 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1103 {
1104 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target reference type");
1105 return;
1106 }
1107
1108 float range = 0.0f;
1109 switch (targetType.GetCheckType())
1110 {
1111 case TARGET_CHECK_ENEMY:
1112 range = m_spellInfo->GetMaxRange(false, m_caster, this);
1113 break;
1114 case TARGET_CHECK_ALLY:
1115 case TARGET_CHECK_PARTY:
1116 case TARGET_CHECK_RAID:
1118 range = m_spellInfo->GetMaxRange(true, m_caster, this);
1119 break;
1120 case TARGET_CHECK_ENTRY:
1123 break;
1124 default:
1125 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented selection check type");
1126 break;
1127 }
1128
1129 std::shared_ptr<ConditionList> condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1130
1131 // handle emergency case - try to use other provided targets if no conditions provided
1132 if (targetType.GetCheckType() == TARGET_CHECK_ENTRY && (!condList || condList->empty()))
1133 {
1134 LOG_DEBUG("spells.aura", "Spell::SelectImplicitNearbyTargets: no conditions entry for target with TARGET_CHECK_ENTRY of spell ID {}, effect {} - selecting default targets", m_spellInfo->Id, effIndex);
1135 switch (targetType.GetObjectType())
1136 {
1139 {
1140 if (focusObject)
1141 AddGOTarget(focusObject, effMask);
1142 return;
1143 }
1144 break;
1147 {
1148 if (focusObject)
1150 return;
1151 }
1152 break;
1153 default:
1154 break;
1155 }
1156 }
1157
1158 WorldObject* target = SearchNearbyTarget(range, targetType.GetObjectType(), targetType.GetCheckType(), condList);
1159 if (!target)
1160 {
1161 LOG_DEBUG("spells.aura", "Spell::SelectImplicitNearbyTargets: cannot find nearby target for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1162 return;
1163 }
1164
1165 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1166 if (!target)
1167 {
1168 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set nullptr target, effect {}", m_spellInfo->Id, effIndex);
1169 return;
1170 }
1171
1172 switch (targetType.GetObjectType())
1173 {
1175 {
1176 if (Unit* unit = target->ToUnit())
1177 {
1178 AddUnitTarget(unit, effMask, true, false);
1179 // xinef: important! if channeling spell have nearby entry, it has no unitTarget by default
1180 // and if channeled spell has target 77, it requires unitTarget, set it here!
1181 // xinef: if we have NO unit target
1182 if (!m_targets.GetUnitTarget())
1183 {
1185 }
1186 }
1187 else
1188 {
1189 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set object of wrong type, expected unit, got {}, effect {}", m_spellInfo->Id, target->GetGUID().GetTypeName(), effMask);
1190 return;
1191 }
1192 break;
1193 }
1195 if (GameObject* gobjTarget = target->ToGameObject())
1196 AddGOTarget(gobjTarget, effMask);
1197 else
1198 {
1199 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set object of wrong type, expected gameobject, got {}, effect {}", m_spellInfo->Id, target->GetGUID().GetTypeName(), effMask);
1200 return;
1201 }
1202 break;
1204 m_targets.SetDst(*target);
1205 break;
1206 default:
1207 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target object type");
1208 break;
1209 }
1210
1211 SelectImplicitChainTargets(effIndex, targetType, target, effMask);
1212}
@ TARGET_CHECK_PARTY
Definition SpellInfo.h:119
@ TARGET_CHECK_ENEMY
Definition SpellInfo.h:117
@ TARGET_CHECK_DEFAULT
Definition SpellInfo.h:115
@ TARGET_CHECK_RAID_CLASS
Definition SpellInfo.h:121
@ TARGET_CHECK_ALLY
Definition SpellInfo.h:118
@ TARGET_CHECK_RAID
Definition SpellInfo.h:120
void SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, WorldObject *target, uint32 effMask)
Definition Spell.cpp:1838
WorldObject * SearchNearbyTarget(float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, std::shared_ptr< ConditionList > condList=nullptr)
Definition Spell.cpp:2167

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), SpellInfo::Effects, focusObject, SpellImplicitTargetInfo::GetCheckType(), SpellInfo::GetMaxRange(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellCastTargets::GetUnitTarget(), SpellInfo::Id, SpellInfo::IsPositive(), LOG_DEBUG, m_caster, m_spellInfo, m_targets, SpellInfo::RequiresSpellFocus, SearchNearbyTarget(), SelectImplicitChainTargets(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), TARGET_CHECK_ALLY, TARGET_CHECK_DEFAULT, TARGET_CHECK_ENEMY, TARGET_CHECK_ENTRY, TARGET_CHECK_PARTY, TARGET_CHECK_RAID, TARGET_CHECK_RAID_CLASS, TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_GOBJ, TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTargetDestTargets()

void Spell::SelectImplicitTargetDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1694{
1696
1697 SpellDestination dest(*target);
1698
1699 switch (targetType.GetTarget())
1700 {
1703 break;
1704 default:
1705 {
1706 float angle = targetType.CalcDirectionAngle();
1707 float dist = m_spellInfo->Effects[effIndex].CalcRadius(nullptr);
1708 if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM)
1709 {
1710 dist *= float(rand_norm());
1711 }
1712
1713 if (targetType.GetTarget() == TARGET_DEST_TARGET_BACK)
1714 {
1716 }
1717
1718 Position pos = dest._position;
1719 target->MovePositionToFirstCollision(pos, dist, angle);
1720
1721 dest.Relocate(pos);
1722 break;
1723 }
1724 }
1725
1726 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1727 m_targets.SetDst(dest);
1728}
@ TARGET_DEST_TARGET_ANY
Definition SharedDefines.h:1478
@ TARGET_DEST_TARGET_BACK
Definition SharedDefines.h:1480
@ TARGET_DEST_TARGET_RANDOM
Definition SharedDefines.h:1489
@ TARGET_DEST_TARGET_ENEMY
Definition SharedDefines.h:1468
@ UNIT_FIELD_BOUNDINGRADIUS
Definition UpdateFields.h:122

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), SpellInfo::Effects, Object::GetFloatValue(), SpellCastTargets::GetObjectTarget(), SpellImplicitTargetInfo::GetTarget(), m_spellInfo, m_targets, WorldObject::MovePositionToFirstCollision(), rand_norm(), SpellDestination::Relocate(), SpellCastTargets::SetDst(), TARGET_DEST_TARGET_ANY, TARGET_DEST_TARGET_BACK, TARGET_DEST_TARGET_ENEMY, TARGET_DEST_TARGET_RANDOM, and UNIT_FIELD_BOUNDINGRADIUS.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTargetObjectTargets()

void Spell::SelectImplicitTargetObjectTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1817{
1818 ASSERT((m_targets.GetObjectTarget() || m_targets.GetItemTarget()) && "Spell::SelectImplicitTargetObjectTargets - no explicit object or item target available!");
1819
1821
1822 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1823
1824 if (target)
1825 {
1826 if (Unit* unit = target->ToUnit())
1827 AddUnitTarget(unit, 1 << effIndex, true, false);
1828 else if (GameObject* gobj = target->ToGameObject())
1829 AddGOTarget(gobj, 1 << effIndex);
1830
1831 SelectImplicitChainTargets(effIndex, targetType, target, 1 << effIndex);
1832 }
1833 // Script hook can remove object target and we would wrongly land here
1834 else if (Item* item = m_targets.GetItemTarget())
1835 AddItemTarget(item, 1 << effIndex);
1836}

References AddGOTarget(), AddItemTarget(), AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetObjectTarget(), m_targets, SelectImplicitChainTargets(), Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTrajTargets()

void Spell::SelectImplicitTrajTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
Todo:
: all calculation should be based on src instead of m_caster
1880{
1881 if (!m_targets.HasTraj())
1882 return;
1883
1884 float dist2d = m_targets.GetDist2d();
1885 if (!dist2d)
1886 return;
1887
1888 float srcToDestDelta = m_targets.GetDstPos()->m_positionZ - m_targets.GetSrcPos()->m_positionZ;
1889
1890 // xinef: supply correct target type, DEST_DEST and similar are ALWAYS undefined
1891 // xinef: correct target is stored in TRIGGERED SPELL, however as far as i noticed, all checks are ENTRY, ENEMY
1892 std::list<WorldObject*> targets;
1893 Acore::WorldObjectSpellTrajTargetCheck check(dist2d, m_targets.GetSrcPos(), m_caster, m_spellInfo, TARGET_CHECK_ENEMY /*targetCheckType*/, m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
1895 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellTrajTargetCheck> > (searcher, GRID_MAP_TYPE_MASK_ALL, m_caster, m_targets.GetSrcPos(), dist2d);
1896 if (targets.empty())
1897 return;
1898
1900
1901 float b = tangent(m_targets.GetElevation());
1902 float a = (srcToDestDelta - dist2d * b) / (dist2d * dist2d);
1903 if (a > -0.0001f)
1904 a = 0;
1905
1906 LOG_DEBUG("spells", "Spell::SelectTrajTargets: a {} b {}", a, b);
1907
1908 // Xinef: hack for distance, many trajectory spells have RangeEntry 1 (self)
1909 float bestDist = m_spellInfo->GetMaxRange(false) * 2;
1910 if (bestDist < 1.0f)
1911 bestDist = 300.0f;
1912
1913 std::list<WorldObject*>::const_iterator itr = targets.begin();
1914 for (; itr != targets.end(); ++itr)
1915 {
1916 if (Unit* unitTarget = (*itr)->ToUnit())
1917 if (m_caster == *itr || m_caster->IsOnVehicle(unitTarget) || (unitTarget)->GetVehicle())//(*itr)->IsOnVehicle(m_caster))
1918 continue;
1919
1920 const float size = std::max((*itr)->GetObjectSize() * 0.7f, 1.0f); // 1/sqrt(3)
1922 const float objDist2d = std::fabs(m_targets.GetSrcPos()->GetExactDist2d(*itr) * cos(m_targets.GetSrcPos()->GetRelativeAngle(*itr)));
1923 const float dz = std::fabs((*itr)->GetPositionZ() - m_targets.GetSrcPos()->m_positionZ);
1924
1925 LOG_DEBUG("spells", "Spell::SelectTrajTargets: check {}, dist between {} {}, height between {} {}.",
1926 (*itr)->GetEntry(), objDist2d - size, objDist2d + size, dz - size, dz + size);
1927
1928 float dist = objDist2d - size;
1929 float height = dist * (a * dist + b);
1930
1931 LOG_DEBUG("spells", "Spell::SelectTrajTargets: dist {}, height {}.", dist, height);
1932
1933 if (dist < bestDist && height < dz + size && height > dz - size)
1934 {
1935 bestDist = dist > 0 ? dist : 0;
1936 break;
1937 }
1938
1939#define CHECK_DIST {\
1940 LOG_DEBUG("spells", "Spell::SelectTrajTargets: dist {}, height {}.", dist, height);\
1941 if (dist > bestDist)\
1942 continue;\
1943 if (dist < objDist2d + size && dist > objDist2d - size)\
1944 {\
1945 bestDist = dist;\
1946 break;\
1947 }\
1948 }
1949
1950 // RP-GG only, search in straight line, as item have no trajectory
1951 if (m_CastItem)
1952 {
1953 if (dist < bestDist && std::fabs(dz) < 6.0f) // closes target, also check Z difference)
1954 {
1955 bestDist = dist;
1956 break;
1957 }
1958
1959 continue;
1960 }
1961
1962 if (!a)
1963 {
1964 // Xinef: everything remade
1965 dist = m_targets.GetSrcPos()->GetExactDist(*itr);
1966 height = m_targets.GetSrcPos()->GetExactDist2d(*itr) * b;
1967
1968 if (height < dz + size * (b + 1) && height > dz - size * (b + 1) && dist < bestDist)
1969 {
1970 bestDist = dist;
1971 break;
1972 }
1973
1974 continue;
1975 }
1976
1977 height = dz - size;
1978 float sqrt1 = b * b + 4 * a * height;
1979 if (sqrt1 > 0)
1980 {
1981 sqrt1 = std::sqrt(sqrt1);
1982 dist = (sqrt1 - b) / (2 * a);
1983 CHECK_DIST;
1984 }
1985
1986 height = dz + size;
1987 float sqrt2 = b * b + 4 * a * height;
1988 if (sqrt2 > 0)
1989 {
1990 sqrt2 = std::sqrt(sqrt2);
1991 dist = (sqrt2 - b) / (2 * a);
1992 CHECK_DIST;
1993
1994 dist = (-sqrt2 - b) / (2 * a);
1995 CHECK_DIST;
1996 }
1997
1998 if (sqrt1 > 0)
1999 {
2000 dist = (-sqrt1 - b) / (2 * a);
2001 CHECK_DIST;
2002 }
2003 }
2004
2006 {
2007 float x = m_targets.GetSrcPos()->m_positionX + cos(m_caster->GetOrientation()) * bestDist;
2008 float y = m_targets.GetSrcPos()->m_positionY + std::sin(m_caster->GetOrientation()) * bestDist;
2009 float z = m_targets.GetSrcPos()->m_positionZ + bestDist * (a * bestDist + b);
2010
2011 if (itr != targets.end())
2012 {
2013 float distSq = (*itr)->GetExactDistSq(x, y, z);
2014 float sizeSq = (*itr)->GetObjectSize();
2015 sizeSq *= sizeSq;
2016 LOG_DEBUG("spells", "Spell::SelectTrajTargets: Initial {} {} {} {} {}", x, y, z, distSq, sizeSq);
2017 if (distSq > sizeSq)
2018 {
2019 float factor = 1 - std::sqrt(sizeSq / distSq);
2020 x += factor * ((*itr)->GetPositionX() - x);
2021 y += factor * ((*itr)->GetPositionY() - y);
2022 z += factor * ((*itr)->GetPositionZ() - z);
2023
2024 distSq = (*itr)->GetExactDistSq(x, y, z);
2025 LOG_DEBUG("spells", "Spell::SelectTrajTargets: Initial {} {} {} {} {}", x, y, z, distSq, sizeSq);
2026 }
2027 }
2028
2029 Position trajDst;
2030 trajDst.Relocate(x, y, z, m_caster->GetOrientation());
2032 dest.Relocate(trajDst);
2033
2034 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
2035 m_targets.ModDst(dest);
2036 }
2037}
float tangent(float x)
Definition Spell.cpp:1865
#define CHECK_DIST
Definition Object.h:792
float GetElevation() const
Definition Spell.h:177
bool IsOnVehicle(Unit const *vehicle) const
Definition Unit.h:1843

References CallScriptDestinationTargetSelectHandlers(), CHECK_DIST, SpellInfo::Effects, SpellCastTargets::GetDist2d(), SpellCastTargets::GetDst(), SpellCastTargets::GetDstPos(), SpellCastTargets::GetElevation(), Position::GetExactDist(), Position::GetExactDist2d(), SpellInfo::GetMaxRange(), Position::GetOrientation(), Position::GetRelativeAngle(), SpellCastTargets::GetSrcPos(), GRID_MAP_TYPE_MASK_ALL, SpellCastTargets::HasTraj(), Unit::IsOnVehicle(), LOG_DEBUG, m_caster, m_CastItem, Position::m_positionX, Position::m_positionY, Position::m_positionZ, m_spellInfo, m_targets, SpellCastTargets::ModDst(), Position::Relocate(), SpellDestination::Relocate(), tangent(), TARGET_CHECK_ENEMY, Object::ToUnit(), and unitTarget.

Referenced by SelectEffectImplicitTargets(), and SelectImplicitDestDestTargets().

◆ SelectSpellTargets()

void Spell::SelectSpellTargets ( )
820{
821 // select targets for cast phase
823
824 uint32 processedAreaEffectsMask = 0;
825 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
826 {
827 // not call for empty effect.
828 // Also some spells use not used effect targets for store targets for dummy effect in triggered spells
829 if (!m_spellInfo->Effects[i].IsEffect())
830 continue;
831
832 // set expected type of implicit targets to be sent to client
833 uint32 implicitTargetMask = GetTargetFlagMask(m_spellInfo->Effects[i].TargetA.GetObjectType()) | GetTargetFlagMask(m_spellInfo->Effects[i].TargetB.GetObjectType());
834 if (implicitTargetMask & TARGET_FLAG_UNIT)
836 if (implicitTargetMask & (TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM))
838
839 SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetA, processedAreaEffectsMask);
840 SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetB, processedAreaEffectsMask);
841
842 // Select targets of effect based on effect type
843 // those are used when no valid target could be added for spell effect based on spell target type
844 // some spell effects use explicit target as a default target added to target map (like SPELL_EFFECT_LEARN_SPELL)
845 // some spell effects add target to target map only when target type specified (like SPELL_EFFECT_WEAPON)
846 // some spell effects don't add anything to target map (confirmed with sniffs) (like SPELL_EFFECT_DESTROY_ALL_TOTEMS)
848
849 if (m_targets.HasDst())
851
853 {
854 // maybe do this for all spells?
855 if (!focusObject && m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty() && m_UniqueItemInfo.empty() && !m_targets.HasDst())
856 {
858 finish(false);
859 return;
860 }
861
862 uint8 mask = (1 << i);
863 for (auto ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
864 {
865 if (ihit->effectMask & mask)
866 {
868 break;
869 }
870 }
871 }
872 else if (m_auraScaleMask)
873 {
874 bool checkLvl = !m_UniqueTargetInfo.empty();
875 m_UniqueTargetInfo.erase(std::remove_if(std::begin(m_UniqueTargetInfo), std::end(m_UniqueTargetInfo), [&](TargetInfo const& targetInfo) -> bool
876 {
877 // remove targets which did not pass min level check
878 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask)
879 {
880 if (!targetInfo.scaleAura && targetInfo.targetGUID != m_caster->GetGUID())
881 return true;
882 }
883
884 return false;
885 }), std::end(m_UniqueTargetInfo));
886
887 if (checkLvl && m_UniqueTargetInfo.empty())
888 {
890 finish(false);
891 }
892 }
893 }
894
895 if (uint64 dstDelay = CalculateDelayMomentForDst())
896 m_delayMoment = dstDelay;
897}
uint32 GetTargetFlagMask(SpellTargetObjectTypes objType)
Definition SpellInfo.cpp:31
@ TARGET_FLAG_GAMEOBJECT
Definition SpellInfo.h:58
@ TARGET_FLAG_GAMEOBJECT_ITEM
Definition SpellInfo.h:61
void SetTargetFlag(SpellCastTargetFlags flag)
Definition Spell.h:129
void SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 &processedEffectMask)
Definition Spell.cpp:926
void SelectExplicitTargets()
Definition Spell.cpp:786
void AddDestTarget(SpellDestination const &dest, uint32 effIndex)
Definition Spell.cpp:2606
void SelectEffectTypeImplicitTargets(uint8 effIndex)
Definition Spell.cpp:2039

References AddDestTarget(), CalculateDelayMomentForDst(), TargetInfo::effectMask, SpellInfo::Effects, finish(), focusObject, SpellCastTargets::GetDst(), GetTargetFlagMask(), SpellCastTargets::HasDst(), SpellInfo::IsChanneled(), m_auraScaleMask, m_channelTargetEffectMask, m_delayMoment, m_spellInfo, m_targets, m_UniqueGOTargetInfo, m_UniqueItemInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SendCastResult(), SpellCastTargets::SetTargetFlag(), SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_LOWLEVEL, TARGET_FLAG_GAMEOBJECT, TARGET_FLAG_GAMEOBJECT_ITEM, and TARGET_FLAG_UNIT.

Referenced by _cast(), CanAutoCast(), spell_dk_raise_dead::CheckCast(), and prepare().

◆ SendCastResult() [1/2]

void Spell::SendCastResult ( Player caster,
SpellInfo const *  spellInfo,
uint8  castCount,
SpellCastResult  result,
SpellCustomErrors  customError = SPELL_CUSTOM_ERROR_NONE 
)
static
4699{
4700 if (result == SPELL_CAST_OK)
4701 return;
4702
4703 WorldPacket data(SMSG_CAST_FAILED, 1 + 4 + 1);
4704 WriteCastResultInfo(data, caster, spellInfo, castCount, result, customError);
4705
4706 caster->GetSession()->SendPacket(&data);
4707}
static void WriteCastResultInfo(WorldPacket &data, Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError)
Definition Spell.cpp:4593
@ SMSG_CAST_FAILED
Definition Opcodes.h:334

References Player::GetSession(), WorldSession::SendPacket(), SMSG_CAST_FAILED, SPELL_CAST_OK, and WriteCastResultInfo().

Referenced by _cast(), Unit::AttackerStateUpdate(), cancel(), Player::CastItemUseSpell(), spell_q12237_rescue_villager::CheckCast(), spell_q12237_drop_off_villager::CheckCast(), spell_dk_raise_dead::CheckReagents(), spell_putricide_mutation_init::CheckRequirement(), EffectApplyGlyph(), EffectDuel(), EffectOpenLock(), EffectTaunt(), SpellScript::FinishCast(), go_soulwell::go_soulwellAI::GossipHello(), WorldSession::HandleAcceptTradeOpcode(), WorldSession::HandleCastSpellOpcode(), spell_the_flag_of_ownership::HandleFinish(), WorldSession::HandlePetActionHelper(), spell_putricide_mutated_transformation::HandleSummon(), misc_commandscript::HandleUnstuckCommand(), icecrown_citadel_teleport::OnGossipSelect(), at_frozen_throne_teleport::OnTrigger(), item_petrov_cluster_bombs::OnUse(), item_only_for_flight::OnUse(), prepare(), SelectImplicitCasterDestTargets(), SelectSpellTargets(), and SendCastResult().

◆ SendCastResult() [2/2]

void Spell::SendCastResult ( SpellCastResult  result)
4710{
4711 if (result == SPELL_CAST_OK)
4712 return;
4713
4714 if (!m_caster->IsPlayer() || m_caster->IsCharmed())
4715 return;
4716
4717 if (m_caster->ToPlayer()->GetSession()->PlayerLoading()) // don't send cast results at loading time
4718 return;
4719
4720 // Xinef: override every possible result, except for gm fail result... breaks many things and goes unnoticed because of this and makes me rage when i find this out
4722 result = SPELL_FAILED_DONT_REPORT;
4723
4725}
@ SPELL_FAILED_BM_OR_INVISGOD
Definition SharedDefines.h:1119
@ TRIGGERED_DONT_REPORT_CAST_ERROR
Disallows proc events from triggered spell (default)
Definition SpellDefines.h:149
bool IsCharmed() const
Definition Unit.h:1239

References Player::GetSession(), HasTriggeredCastFlag(), Unit::IsCharmed(), Object::IsPlayer(), m_cast_count, m_caster, m_customError, m_spellInfo, WorldSession::PlayerLoading(), SendCastResult(), SPELL_CAST_OK, SPELL_FAILED_BM_OR_INVISGOD, SPELL_FAILED_DONT_REPORT, Object::ToPlayer(), and TRIGGERED_DONT_REPORT_CAST_ERROR.

◆ SendChannelStart()

void Spell::SendChannelStart ( uint32  duration)
5236{
5237 ObjectGuid channelTarget = m_targets.GetObjectTargetGUID();
5238 if (!channelTarget && !m_spellInfo->NeedsExplicitUnitTarget())
5239 if (m_UniqueTargetInfo.size() + m_UniqueGOTargetInfo.size() == 1) // this is for TARGET_SELECT_CATEGORY_NEARBY
5240 channelTarget = !m_UniqueTargetInfo.empty() ? m_UniqueTargetInfo.front().targetGUID : m_UniqueGOTargetInfo.front().targetGUID;
5241
5242 WorldPacket data(MSG_CHANNEL_START, (8 + 4 + 4));
5243 data << m_caster->GetPackGUID();
5244 data << uint32(m_spellInfo->Id);
5245 data << uint32(duration);
5246
5247 m_caster->SendMessageToSet(&data, true);
5248
5251
5252 m_timer = duration;
5253 if (channelTarget)
5255
5257}
@ MSG_CHANNEL_START
Definition Opcodes.h:343

References WorldObject::FindMap(), Object::GetGUID(), SpellCastTargets::GetObjectTargetGUID(), Object::GetPackGUID(), SpellInfo::Id, Object::IsPlayer(), m_caster, m_spellInfo, m_targets, m_timer, m_UniqueGOTargetInfo, m_UniqueTargetInfo, MSG_CHANNEL_START, Player::NeedSendSpectatorData(), SpellInfo::NeedsExplicitUnitTarget(), ArenaSpectator::SendCommand_Spell(), WorldObject::SendMessageToSet(), Object::SetGuidValue(), Unit::SetUInt32Value(), Object::ToPlayer(), UNIT_CHANNEL_SPELL, and UNIT_FIELD_CHANNEL_OBJECT.

Referenced by handle_immediate().

◆ SendChannelUpdate()

◆ SendInterrupted()

void Spell::SendInterrupted ( uint8  result)
5204{
5205 WorldPacket data(SMSG_SPELL_FAILURE, (8 + 1 + 4 + 1));
5206 data << m_caster->GetPackGUID();
5207 data << uint8(m_cast_count);
5208 data << uint32(m_spellInfo->Id);
5209 data << uint8(result);
5210 m_caster->SendMessageToSet(&data, true);
5211
5212 data.Initialize(SMSG_SPELL_FAILED_OTHER, (8 + 1 + 4 + 1));
5213 data << m_caster->GetPackGUID();
5214 data << uint8(m_cast_count);
5215 data << uint32(m_spellInfo->Id);
5216 data << uint8(result);
5217 m_caster->SendMessageToSet(&data, true);
5218}
@ SMSG_SPELL_FAILURE
Definition Opcodes.h:337
@ SMSG_SPELL_FAILED_OTHER
Definition Opcodes.h:708

References Object::GetPackGUID(), SpellInfo::Id, WorldPacket::Initialize(), m_cast_count, m_caster, m_spellInfo, WorldObject::SendMessageToSet(), SMSG_SPELL_FAILED_OTHER, and SMSG_SPELL_FAILURE.

Referenced by _cast(), Unit::AttackerStateUpdate(), and cancel().

◆ SendLogExecute()

void Spell::SendLogExecute ( )
5103{
5104 WorldPacket data(SMSG_SPELLLOGEXECUTE, (8 + 4 + 4 + 4 + 4 + 8));
5105
5106 data << m_caster->GetPackGUID();
5107
5108 data << uint32(m_spellInfo->Id);
5109
5110 uint8 effCount = 0;
5111 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5112 {
5113 if (m_effectExecuteData[i])
5114 ++effCount;
5115 }
5116
5117 if (!effCount)
5118 return;
5119
5120 data << uint32(effCount);
5121 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5122 {
5123 if (!m_effectExecuteData[i])
5124 continue;
5125
5126 data << uint32(m_spellInfo->Effects[i].Effect); // spell effect
5127
5128 data.append(*m_effectExecuteData[i]);
5129
5130 delete m_effectExecuteData[i];
5131 m_effectExecuteData[i] = nullptr;
5132 }
5133 m_caster->SendMessageToSet(&data, true);
5134}
@ SMSG_SPELLLOGEXECUTE
Definition Opcodes.h:618

References ByteBuffer::append(), SpellInfo::Effects, Object::GetPackGUID(), SpellInfo::Id, m_caster, m_effectExecuteData, m_spellInfo, MAX_SPELL_EFFECTS, WorldObject::SendMessageToSet(), and SMSG_SPELLLOGEXECUTE.

Referenced by FinishTargetProcessing().

◆ SendLoot()

void Spell::SendLoot ( ObjectGuid  guid,
LootType  loottype 
)
protected
2016{
2017 Player* player = m_caster->ToPlayer();
2018 if (!player)
2019 return;
2020
2021 if (gameObjTarget)
2022 {
2023 // Players shouldn't be able to loot gameobjects that are currently despawned
2024 if (!gameObjTarget->isSpawned() && !player->IsGameMaster())
2025 {
2026 LOG_ERROR("spells.effect", "Possible hacking attempt: Player {} [{}] tried to loot a gameobject [{}] which is on respawn time without being in GM mode!",
2027 player->GetName(), player->GetGUID().ToString(), gameObjTarget->GetGUID().ToString());
2028 return;
2029 }
2030 // special case, already has GossipHello inside so return and avoid calling twice
2032 {
2034 return;
2035 }
2036
2037 if (sScriptMgr->OnGossipHello(player, gameObjTarget))
2038 return;
2039
2040 if (gameObjTarget->AI()->GossipHello(player, false))
2041 return;
2042
2043 switch (gameObjTarget->GetGoType())
2044 {
2046 gameObjTarget->UseDoorOrButton(0, false, player);
2047 return;
2049 gameObjTarget->UseDoorOrButton(0, false, player);
2050
2051 // Xinef: properly link possible traps
2052 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->button.linkedTrap)
2053 gameObjTarget->TriggeringLinkedGameObject(trapEntry, player);
2054 return;
2058 return;
2059
2061 // triggering linked GO
2064 return;
2065
2067 // triggering linked GO
2068 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->chest.linkedTrapId)
2070
2071 // Don't return, let loots been taken
2072 default:
2073 break;
2074 }
2075 }
2076
2077 // Send loot
2078 player->SendLoot(guid, loottype);
2079}
@ GAMEOBJECT_TYPE_SPELL_FOCUS
Definition SharedDefines.h:1579
@ GAMEOBJECT_TYPE_QUESTGIVER
Definition SharedDefines.h:1573
virtual bool GossipHello(Player *, bool)
Definition GameObjectAI.h:54
bool isSpawned() const
Definition GameObject.h:189
void TriggeringLinkedGameObject(uint32 trapEntry, Unit *target)
Definition GameObject.cpp:1366
void SendPreparedGossip(WorldObject *source)
Definition PlayerGossip.cpp:209
void PrepareGossipMenu(WorldObject *source, uint32 menuId=0, bool showQuests=false)
Definition PlayerGossip.cpp:32
struct GameObjectTemplate::@232::@236 questgiver
uint32 gossipID
Definition GameObjectData.h:72
uint32 linkedTrap
Definition GameObjectData.h:59
struct GameObjectTemplate::@232::@241 spellFocus
struct GameObjectTemplate::@232::@237 chest
uint32 linkedTrapId
Definition GameObjectData.h:90

References GameObject::AI(), GameObjectTemplate::button, GameObjectTemplate::chest, GAMEOBJECT_TYPE_BUTTON, GAMEOBJECT_TYPE_CHEST, GAMEOBJECT_TYPE_DOOR, GAMEOBJECT_TYPE_GOOBER, GAMEOBJECT_TYPE_QUESTGIVER, GAMEOBJECT_TYPE_SPELL_FOCUS, gameObjTarget, GameObject::GetGOInfo(), GameObject::GetGoType(), Object::GetGUID(), WorldObject::GetName(), GameObjectAI::GossipHello(), GameObjectTemplate::gossipID, Player::IsGameMaster(), GameObject::isSpawned(), GameObjectTemplate::linkedTrap, GameObjectTemplate::linkedTrapId, LOG_ERROR, m_caster, Player::PrepareGossipMenu(), GameObjectTemplate::questgiver, Player::SendLoot(), Player::SendPreparedGossip(), GameObjectTemplate::spellFocus, sScriptMgr, Object::ToPlayer(), ObjectGuid::ToString(), GameObject::TriggeringLinkedGameObject(), GameObject::Use(), and GameObject::UseDoorOrButton().

Referenced by EffectOpenLock().

◆ SendPetCastResult()

void Spell::SendPetCastResult ( SpellCastResult  result)
4728{
4729 if (result == SPELL_CAST_OK)
4730 return;
4731
4732 Unit* owner = m_caster->GetCharmerOrOwner();
4733 if (!owner)
4734 return;
4735
4736 Player* player = owner->ToPlayer();
4737 if (!player)
4738 return;
4739
4740 WorldPacket data(SMSG_PET_CAST_FAILED, 1 + 4 + 1);
4742
4743 player->GetSession()->SendPacket(&data);
4744}
@ SMSG_PET_CAST_FAILED
Definition Opcodes.h:342

References Unit::GetCharmerOrOwner(), Player::GetSession(), m_cast_count, m_caster, m_customError, m_spellInfo, WorldSession::SendPacket(), SMSG_PET_CAST_FAILED, SPELL_CAST_OK, Object::ToPlayer(), and WriteCastResultInfo().

Referenced by WorldSession::HandlePetActionHelper(), and WorldSession::HandlePetCastSpellOpcode().

◆ SendResurrectRequest()

void Spell::SendResurrectRequest ( Player target)
5260{
5261 // get resurrector name for creature resurrections, otherwise packet will be not accepted
5262 // for player resurrections the name is looked up by guid
5263 std::string const sentName(m_caster->IsPlayer()
5264 ? ""
5265 : m_caster->GetNameForLocaleIdx(target->GetSession()->GetSessionDbLocaleIndex()));
5266
5267 WorldPacket data(SMSG_RESURRECT_REQUEST, (8 + 4 + sentName.size() + 1 + 1 + 1 + 4));
5268 data << m_caster->GetGUID();
5269 data << uint32(sentName.size() + 1);
5270
5271 data << sentName;
5272 data << uint8(0); // null terminator
5273
5274 data << uint8(m_caster->IsPlayer() ? 0 : 1); // "you'll be afflicted with resurrection sickness"
5275 // override delay sent with SMSG_CORPSE_RECLAIM_DELAY, set instant resurrection for spells with this attribute
5277 data << uint32(0);
5278 target->GetSession()->SendPacket(&data);
5279}
@ SPELL_ATTR3_NO_RES_TIMER
Definition SharedDefines.h:508
@ SMSG_RESURRECT_REQUEST
Definition Opcodes.h:377

References Object::GetGUID(), WorldObject::GetNameForLocaleIdx(), Player::GetSession(), WorldSession::GetSessionDbLocaleIndex(), SpellInfo::HasAttribute(), Object::IsPlayer(), m_caster, m_spellInfo, WorldSession::SendPacket(), SMSG_RESURRECT_REQUEST, and SPELL_ATTR3_NO_RES_TIMER.

Referenced by EffectResurrect(), and EffectResurrectNew().

◆ SendSpellCooldown()

void Spell::SendSpellCooldown ( )
4375{
4376 // xinef: properly add creature cooldowns
4377 if (!m_caster->IsPlayer())
4378 {
4380 {
4381 // xinef: this should be added here
4382 //m_caster->AddSpellCooldown(m_spellInfo->Id, 0, 0);
4383
4384 // xinef: this adds cooldowns to vehicle spells which misses them client-side (when we overwrote dbc info in eg.)
4387 {
4388 WorldPacket data(SMSG_SPELL_COOLDOWN, 8 + 1 + 4 + 4);
4389 data << m_caster->GetGUID();
4391 data << uint32(m_spellInfo->Id);
4393 player->SendDirectMessage(&data);
4394 }
4395 }
4396 return;
4397 }
4398
4399 Player* _player = m_caster->ToPlayer();
4400
4401 // mana/health/etc potions, disabled by client (until combat out as declarate)
4403 {
4404 // need in some way provided data for Spell::finish SendCooldownEvent
4405 _player->SetLastPotionId(m_CastItem->GetEntry());
4406 return;
4407 }
4408
4409 // have infinity cooldown but set at aura apply
4410 // do not set cooldown for triggered spells (needed by reincarnation)
4415 return;
4416
4418}
@ SPELL_COOLDOWN_FLAG_INCLUDE_GCD
Starts GCD in addition to normal cooldown specified in the packet.
Definition Unit.h:607
void SetLastPotionId(uint32 item_id)
Definition Player.h:1815
void AddSpellAndCategoryCooldowns(SpellInfo const *spellInfo, uint32 itemId, Spell *spell=nullptr, bool infinityCooldown=false)
Definition Player.cpp:10946
uint32 RecoveryTime
Definition SpellInfo.h:349
bool RequireCooldownInfo() const
Definition SpellInfo.cpp:1177
@ SMSG_SPELL_COOLDOWN
Definition Opcodes.h:338

References Player::AddSpellAndCategoryCooldowns(), Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), Object::GetEntry(), Object::GetGUID(), HasTriggeredCastFlag(), SpellInfo::Id, SpellInfo::IsCooldownStartedOnEvent(), SpellInfo::IsPassive(), Object::IsPlayer(), Item::IsPotion(), m_caster, m_CastItem, m_spellInfo, SpellInfo::RecoveryTime, SpellInfo::RequireCooldownInfo(), Player::SetLastPotionId(), SMSG_SPELL_COOLDOWN, SPELL_COOLDOWN_FLAG_INCLUDE_GCD, Object::ToPlayer(), TRIGGERED_IGNORE_EFFECTS, and TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD.

Referenced by _cast().

◆ SendSpellGo()

void Spell::SendSpellGo ( )
4827{
4828 // not send invisible spell casting
4829 if (!IsNeedSendToClient(true))
4830 return;
4831
4832 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_GO id={}", m_spellInfo->Id);
4833
4834 uint32 castFlags = CAST_FLAG_UNKNOWN_9;
4835
4836 // triggered spells with spell visual != 0
4838 castFlags |= CAST_FLAG_PENDING;
4839
4841 castFlags |= CAST_FLAG_PROJECTILE; // arrows/bullets visual
4842
4843 // should only be sent to self, but the current messaging doesn't make that possible
4844 if (m_caster->IsPlayer() || m_caster->IsPet())
4845 {
4846 switch (m_spellInfo->PowerType)
4847 {
4848 case POWER_HEALTH:
4849 break;
4850 case POWER_RUNE:
4851 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4852 break;
4853 default:
4854 if (m_powerCost != 0)
4855 {
4856 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4857 }
4858 break;
4859 }
4860 }
4861
4862 if ((m_caster->IsPlayer())
4866 {
4867 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4868 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4869 }
4870
4872 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4873
4874 if (m_targets.HasTraj())
4875 castFlags |= CAST_FLAG_ADJUST_MISSILE;
4876
4878 castFlags |= CAST_FLAG_NO_GCD;
4879
4880 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4881 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4882 {
4883 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4884 {
4885 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4886 {
4887 realCasterGUID = casterGameobject->GetPackGUID();
4888 }
4889 }
4890 }
4891
4892 WorldPacket data(SMSG_SPELL_GO, 150); // guess size
4893
4894 if (m_CastItem)
4895 data << m_CastItem->GetPackGUID();
4896 else
4897 data << realCasterGUID;
4898
4899 data << realCasterGUID;
4900 data << uint8(m_cast_count); // pending spell cast?
4901 data << uint32(m_spellInfo->Id); // spellId
4902 data << uint32(castFlags); // cast flags
4903 data << uint32(GameTime::GetGameTimeMS().count()); // timestamp
4904
4905 WriteSpellGoTargets(&data);
4906
4907 m_targets.Write(data);
4908
4909 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4911
4912 if (castFlags & CAST_FLAG_RUNE_LIST) // rune cooldowns list
4913 {
4914 //TODO: There is a crash caused by a spell with CAST_FLAG_RUNE_LIST casted by a creature
4915 //The creature is the mover of a player, so HandleCastSpellOpcode uses it as the caster
4916 if (Player* player = m_caster->ToPlayer())
4917 {
4918 uint8 runeMaskInitial = m_runesState;
4919 uint8 runeMaskAfterCast = player->GetRunesState();
4920 data << uint8(runeMaskInitial); // runes state before
4921 data << uint8(runeMaskAfterCast); // runes state after
4922 for (uint8 i = 0; i < MAX_RUNES; ++i)
4923 {
4924 uint8 mask = (1 << i);
4925 if (mask & runeMaskInitial && !(mask & runeMaskAfterCast)) // usable before andon cooldown now...
4926 {
4927 // float casts ensure the division is performed on floats as we need float result
4928 float baseCd = float(player->GetRuneBaseCooldown(i, true));
4929 data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed
4930 }
4931 }
4932 }
4933 }
4934 if (castFlags & CAST_FLAG_ADJUST_MISSILE)
4935 {
4936 data << m_targets.GetElevation();
4938 }
4939
4940 if (castFlags & CAST_FLAG_PROJECTILE)
4941 WriteAmmoToPacket(&data);
4942
4943 if (castFlags & CAST_FLAG_VISUAL_CHAIN)
4944 {
4945 data << uint32(0);
4946 data << uint32(0);
4947 }
4948
4950 {
4951 data << uint8(0);
4952 }
4953
4954 m_caster->SendMessageToSet(&data, true);
4955}
@ SPELL_EFFECT_ACTIVATE_RUNE
Definition SharedDefines.h:935
@ SPELL_ATTR0_USES_RANGED_SLOT
Definition SharedDefines.h:394
@ SPELL_ATTR0_CU_NEEDS_AMMO_DATA
Definition SpellInfo.h:196
@ CAST_FLAG_VISUAL_CHAIN
Definition Spell.h:65
@ CAST_FLAG_ADJUST_MISSILE
Definition Spell.h:63
@ CAST_FLAG_UNKNOWN_9
Definition Spell.h:54
@ CAST_FLAG_NO_GCD
Definition Spell.h:64
@ CAST_FLAG_PROJECTILE
Definition Spell.h:51
@ CAST_FLAG_POWER_LEFT_SELF
Definition Spell.h:57
@ CAST_FLAG_RUNE_LIST
Definition Spell.h:67
@ CAST_FLAG_PENDING
Definition Spell.h:46
Definition ObjectGuid.h:263
void Write(ByteBuffer &data)
Definition Spell.cpp:179
SpellCastTimesEntry const * CastTimeEntry
Definition SpellInfo.h:348
void WriteSpellGoTargets(WorldPacket *data)
Writes miss and hit targets for a SMSG_SPELL_GO packet.
Definition Spell.cpp:5042
void WriteAmmoToPacket(WorldPacket *data)
Definition Spell.cpp:4957
bool IsNeedSendToClient(bool go) const
Definition Spell.cpp:8136
@ SMSG_SPELL_GO
Definition Opcodes.h:336
int32 CastTime
Definition DBCStructure.h:1761

References CAST_FLAG_ADJUST_MISSILE, CAST_FLAG_NO_GCD, CAST_FLAG_PENDING, CAST_FLAG_POWER_LEFT_SELF, CAST_FLAG_PROJECTILE, CAST_FLAG_RUNE_LIST, CAST_FLAG_UNKNOWN_9, CAST_FLAG_VISUAL_CHAIN, SpellCastTimesEntry::CastTime, SpellInfo::CastTimeEntry, CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, SpellCastTargets::GetElevation(), GameTime::GetGameTimeMS(), Object::GetPackGUID(), Unit::GetPower(), SpellCastTargets::GetTargetMask(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), SpellCastTargets::HasTraj(), SpellInfo::Id, SpellInfo::IsAutoRepeatRangedSpell(), SpellInfo::IsChanneled(), Unit::IsClass(), IsNeedSendToClient(), Unit::IsPet(), Object::IsPlayer(), IsTriggered(), m_cast_count, m_caster, m_CastItem, m_delayMoment, m_delayTrajectory, m_powerCost, m_runesState, m_spellInfo, m_targets, m_triggeredByAuraSpell, MAX_RUNES, POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, WorldObject::SendMessageToSet(), SMSG_SPELL_GO, SPELL_ATTR0_CU_NEEDS_AMMO_DATA, SPELL_ATTR0_USES_RANGED_SLOT, SPELL_EFFECT_ACTIVATE_RUNE, SpellInfo::StartRecoveryTime, TARGET_FLAG_DEST_LOCATION, Object::ToPlayer(), Unit::ToTempSummon(), WORLD_TRIGGER, SpellCastTargets::Write(), WriteAmmoToPacket(), and WriteSpellGoTargets().

Referenced by _cast().

◆ SendSpellStart()

void Spell::SendSpellStart ( )
4747{
4748 if (!IsNeedSendToClient(false))
4749 return;
4750
4751 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_START id={}", m_spellInfo->Id);
4752
4753 uint32 castFlags = CAST_FLAG_HAS_TRAJECTORY;
4754
4756 castFlags |= CAST_FLAG_PENDING;
4757
4759 castFlags |= CAST_FLAG_PROJECTILE;
4760
4761 if (m_caster->IsPlayer() || m_caster->IsPet())
4762 {
4763 switch (m_spellInfo->PowerType)
4764 {
4765 case POWER_HEALTH:
4766 break;
4767 case POWER_RUNE:
4768 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4769 break;
4770 default:
4771 if (m_powerCost != 0)
4772 {
4773 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4774 }
4775 break;
4776 }
4777 }
4778
4780 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4781
4782 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4783 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4784 {
4785 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4786 {
4787 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4788 {
4789 realCasterGUID = casterGameobject->GetPackGUID();
4790 }
4791 }
4792 }
4793
4794 WorldPacket data(SMSG_SPELL_START, (8 + 8 + 4 + 4 + 2));
4795 if (m_CastItem)
4796 data << m_CastItem->GetPackGUID();
4797 else
4798 data << realCasterGUID;
4799
4800 data << realCasterGUID;
4801 data << uint8(m_cast_count); // pending spell cast?
4802 data << uint32(m_spellInfo->Id); // spellId
4803 data << uint32(castFlags); // cast flags
4804 data << int32(m_timer); // delay?
4805
4806 m_targets.Write(data);
4807
4808 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4810
4811 if (castFlags & CAST_FLAG_PROJECTILE)
4812 WriteAmmoToPacket(&data);
4813
4814 if (castFlags & CAST_FLAG_UNKNOWN_23)
4815 {
4816 data << uint32(0);
4817 data << uint32(0);
4818 }
4819
4820 m_caster->SendMessageToSet(&data, true);
4821
4824}
@ CAST_FLAG_UNKNOWN_23
Definition Spell.h:68
@ CAST_FLAG_HAS_TRAJECTORY
Definition Spell.h:47
@ SMSG_SPELL_START
Definition Opcodes.h:335

References CAST_FLAG_HAS_TRAJECTORY, CAST_FLAG_NO_GCD, CAST_FLAG_PENDING, CAST_FLAG_POWER_LEFT_SELF, CAST_FLAG_PROJECTILE, CAST_FLAG_UNKNOWN_23, SpellCastTimesEntry::CastTime, SpellInfo::CastTimeEntry, WorldObject::FindMap(), Object::GetGUID(), Object::GetPackGUID(), Unit::GetPower(), SpellInfo::HasAttribute(), SpellInfo::Id, SpellInfo::IsAutoRepeatRangedSpell(), SpellInfo::IsChanneled(), IsNeedSendToClient(), Unit::IsPet(), Object::IsPlayer(), IsTriggered(), m_cast_count, m_caster, m_CastItem, m_powerCost, m_spellInfo, m_targets, m_timer, m_triggeredByAuraSpell, Player::NeedSendSpectatorData(), POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, ArenaSpectator::SendCommand_Spell(), WorldObject::SendMessageToSet(), SMSG_SPELL_START, SPELL_ATTR0_CU_NEEDS_AMMO_DATA, SPELL_ATTR0_USES_RANGED_SLOT, Object::ToPlayer(), Unit::ToTempSummon(), WORLD_TRIGGER, SpellCastTargets::Write(), and WriteAmmoToPacket().

Referenced by prepare().

◆ SetAutoRepeat()

void Spell::SetAutoRepeat ( bool  rep)
inline
572{ m_autoRepeat = rep; }

References m_autoRepeat.

◆ SetDelayStart()

void Spell::SetDelayStart ( uint64  m_time)
inline
587{ m_delayStart = m_time; }

References m_delayStart.

Referenced by _cast(), and SpellEvent::Execute().

◆ SetExecutedCurrently()

void Spell::SetExecutedCurrently ( bool  yes)
inline
585{m_executedCurrently = yes;}

References m_executedCurrently.

Referenced by _cast(), and Unit::AttackerStateUpdate().

◆ SetReferencedFromCurrent()

void Spell::SetReferencedFromCurrent ( bool  yes)
inline

◆ SetSpellValue()

void Spell::SetSpellValue ( SpellValueMod  mod,
int32  value 
)
8479{
8480 switch (mod)
8481 {
8483 m_spellValue->EffectBasePoints[0] = m_spellInfo->Effects[EFFECT_0].CalcBaseValue(value);
8484 break;
8486 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(value);
8487 break;
8489 m_spellValue->EffectBasePoints[2] = m_spellInfo->Effects[EFFECT_2].CalcBaseValue(value);
8490 break;
8492 m_spellValue->RadiusMod = (float)value / 10000;
8493 break;
8496 break;
8499 break;
8501 m_spellValue->AuraDuration = value;
8502 break;
8504 m_spellValue->ForcedCritResult = (bool)value;
8505 break;
8507 m_spellValue->MiscVal[0] = value;
8508 break;
8510 m_spellValue->MiscVal[1] = value;
8511 break;
8513 m_spellValue->MiscVal[2] = value;
8514 break;
8515 }
8516}
@ SPELLVALUE_AURA_STACK
Definition SpellDefines.h:118
@ SPELLVALUE_MISCVALUE1
Definition SpellDefines.h:122
@ SPELLVALUE_AURA_DURATION
Definition SpellDefines.h:119
@ SPELLVALUE_MISCVALUE2
Definition SpellDefines.h:123
@ SPELLVALUE_RADIUS_MOD
Definition SpellDefines.h:116
@ SPELLVALUE_MAX_TARGETS
Definition SpellDefines.h:117
@ SPELLVALUE_FORCED_CRIT_RESULT
Definition SpellDefines.h:120
@ SPELLVALUE_MISCVALUE0
Definition SpellDefines.h:121
bool ForcedCritResult
Definition Spell.h:227

References SpellValue::AuraDuration, SpellValue::AuraStackAmount, EFFECT_0, EFFECT_1, EFFECT_2, SpellValue::EffectBasePoints, SpellInfo::Effects, SpellValue::ForcedCritResult, m_spellInfo, m_spellValue, SpellValue::MaxAffectedTargets, SpellValue::MiscVal, SpellValue::RadiusMod, SPELLVALUE_AURA_DURATION, SPELLVALUE_AURA_STACK, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, SPELLVALUE_FORCED_CRIT_RESULT, SPELLVALUE_MAX_TARGETS, SPELLVALUE_MISCVALUE0, SPELLVALUE_MISCVALUE1, SPELLVALUE_MISCVALUE2, and SPELLVALUE_RADIUS_MOD.

Referenced by Player::CastItemUseSpell(), Unit::CastSpell(), and spell_gen_mod_radius_by_caster_scale::PrepareSpellScript().

◆ setState()

void Spell::setState ( uint32  state)
inline
506{ m_spellState = state; }

References m_spellState.

◆ SummonGuardian()

void Spell::SummonGuardian ( uint32  i,
uint32  entry,
SummonPropertiesEntry const *  properties,
uint32  numSummons,
bool  personalSpawn 
)
protected
5950{
5951 Unit* caster = m_originalCaster;
5952 if (!caster)
5953 return;
5954
5955 if (caster->IsTotem())
5956 caster = caster->ToTotem()->GetOwner();
5957
5958 // in another case summon new
5959 uint8 summonLevel = caster->GetLevel();
5960
5961 // level of pet summoned using engineering item based at engineering skill level
5962 if (m_CastItem && caster->IsPlayer())
5963 if (ItemTemplate const* proto = m_CastItem->GetTemplate())
5964 {
5965 // xinef: few special cases
5966 if (proto->RequiredSkill == SKILL_ENGINEERING)
5967 {
5968 if (uint16 skill202 = caster->ToPlayer()->GetSkillValue(SKILL_ENGINEERING))
5969 summonLevel = skill202 / 5;
5970 }
5971
5972 switch (m_spellInfo->Id)
5973 {
5974 // Dragon's Call
5975 case 13049:
5976 summonLevel = 55;
5977 break;
5978
5979 // Cleansed Timberling Heart: Summon Timberling
5980 case 5666:
5981 summonLevel = 7;
5982 break;
5983
5984 // Glowing Cat Figurine: Summon Ghost Saber
5985 case 6084:
5986 // minLevel 19, maxLevel 20
5987 summonLevel = 20;
5988 break;
5989
5990 // Spiked Collar: Summon Felhunter
5991 case 8176:
5992 summonLevel = 30;
5993 break;
5994
5995 // Dog Whistle: Summon Tracking Hound
5996 case 9515:
5997 summonLevel = 30;
5998 break;
5999
6000 // Barov Peasant Caller: Death by Peasant
6001 case 18307:
6002 case 18308:
6003 summonLevel = 60;
6004 break;
6005
6006 // Thornling Seed: Plant Thornling
6007 case 22792:
6008 summonLevel = 60;
6009 break;
6010
6011 // Cannonball Runner: Summon Crimson Cannon
6012 case 6251:
6013 summonLevel = 61;
6014 break;
6015 }
6016 }
6017
6018 summonLevel = std::min<uint8>(sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) + sWorld->getIntConfig(CONFIG_WORLD_BOSS_LEVEL_DIFF), std::max<uint8>(1U, summonLevel));
6019
6020 float radius = 5.0f;
6021 int32 duration = m_spellInfo->GetDuration();
6022
6023 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
6024 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
6025
6026 //TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
6027 Map* map = caster->GetMap();
6028 TempSummon* summon = nullptr;
6029
6030 uint32 currMinionsCount = m_caster->m_Controlled.size();
6031 uint32 totalNumGuardians = numGuardians + currMinionsCount;
6032
6033 for (uint32 count = 0; count < numGuardians; ++count)
6034 {
6035 Position pos;
6036
6037 // xinef: do not use precalculated position for effect summon pet in this function
6038 // it means it was cast by NPC and should have its position overridden unless the
6039 // target position is specified in the DB AND the effect has no or zero radius
6040 if ((totalNumGuardians == 1 && GetSpellInfo()->Effects[i].Effect != SPELL_EFFECT_SUMMON_PET) ||
6041 (GetSpellInfo()->Effects[i].TargetA.GetTarget() == TARGET_DEST_DB &&
6042 (!GetSpellInfo()->Effects[i].HasRadius() || GetSpellInfo()->Effects[i].RadiusEntry->RadiusMax == 0)))
6043 {
6044 pos = *destTarget;
6045 }
6046 else
6047 {
6048 // randomize position
6049 pos = m_caster->GetRandomPoint(*destTarget, radius);
6050 }
6051
6052 summon = map->SummonCreature(entry, pos, properties, duration, caster, m_spellInfo->Id, 0, personalSpawn);
6053 if (!summon)
6054 return;
6055
6056 // xinef: set calculated level
6057 summon->SetLevel(summonLevel);
6058
6059 // if summonLevel changed, set stats for calculated level
6060 if (summonLevel != caster->GetLevel())
6061 {
6062 ((Guardian*)summon)->InitStatsForLevel(summonLevel);
6063 }
6064
6065 // xinef: if we have more than one guardian, change follow angle
6066 if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && totalNumGuardians > 1)
6067 ((Minion*)summon)->SetFollowAngle(m_caster->GetAbsoluteAngle(pos.GetPositionX(), pos.GetPositionY()));
6068 //else if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && m_targets.HasDst())
6069 // ((Minion*)summon)->SetFollowAngle(m_caster->GetAngle(summon));
6070
6071 // xinef: move this here, some auras are added in initstatsforlevel!
6072 if (!summon->IsInCombat() && !summon->IsTrigger())
6073 {
6074 // summon->AI()->EnterEvadeMode();
6075 summon->GetMotionMaster()->Clear(false);
6077 }
6078
6079 if (properties && properties->Category == SUMMON_CATEGORY_ALLY)
6080 summon->SetFaction(caster->GetFaction());
6081
6083 }
6084}
@ SKILL_ENGINEERING
Definition SharedDefines.h:3173
@ CONFIG_MAX_PLAYER_LEVEL
Definition WorldConfig.h:189
@ CONFIG_WORLD_BOSS_LEVEL_DIFF
Definition WorldConfig.h:238
bool IsTrigger() const
Definition Creature.h:76
Definition TemporarySummon.h:77
Unit * GetOwner() const
Definition TemporarySummon.cpp:386
void SetLevel(uint8 lvl, bool showLevelChange=true)
Definition Unit.cpp:15561

References SummonPropertiesEntry::Category, MotionMaster::Clear(), CONFIG_MAX_PLAYER_LEVEL, CONFIG_WORLD_BOSS_LEVEL_DIFF, destTarget, ExecuteLogEffectSummonObject(), Position::GetAbsoluteAngle(), SpellInfo::GetDuration(), Unit::GetFaction(), Unit::GetFollowAngle(), Unit::GetLevel(), WorldObject::GetMap(), Unit::GetMotionMaster(), Minion::GetOwner(), Position::GetPositionX(), Position::GetPositionY(), WorldObject::GetRandomPoint(), Player::GetSkillValue(), GetSpellInfo(), Unit::GetSpellModOwner(), Item::GetTemplate(), Unit::HasUnitTypeMask(), SpellInfo::Id, Unit::IsInCombat(), Object::IsPlayer(), Unit::IsTotem(), Creature::IsTrigger(), m_caster, m_CastItem, Unit::m_Controlled, m_originalCaster, m_spellInfo, MOTION_SLOT_ACTIVE, MotionMaster::MoveFollow(), PET_FOLLOW_DIST, Unit::SetFaction(), Unit::SetLevel(), SKILL_ENGINEERING, SPELL_EFFECT_SUMMON_PET, SPELLMOD_DURATION, SUMMON_CATEGORY_ALLY, Map::SummonCreature(), sWorld, TARGET_DEST_DB, Object::ToPlayer(), Unit::ToTotem(), and UNIT_MASK_MINION.

Referenced by EffectSummonPet(), and EffectSummonType().

◆ TakeAmmo()

void Spell::TakeAmmo ( )
5409{
5411 {
5413
5414 // wands don't have ammo
5415 if (!pItem || pItem->IsBroken() || pItem->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_WAND)
5416 return;
5417
5418 if (pItem->GetTemplate()->InventoryType == INVTYPE_THROWN)
5419 {
5420 if (pItem->GetMaxStackCount() == 1)
5421 {
5422 // decrease durability for non-stackable throw weapon
5424 }
5425 else if (!sWorld->getBoolConfig(CONFIG_ENABLE_INFINITEAMMO))
5426 {
5427 // decrease items amount for stackable throw weapon
5428 uint32 count = 1;
5429 m_caster->ToPlayer()->DestroyItemCount(pItem, count, true);
5430 }
5431 }
5432 else if (!sWorld->getBoolConfig(CONFIG_ENABLE_INFINITEAMMO))
5434 m_caster->ToPlayer()->DestroyItemCount(ammo, 1, true);
5435 }
5436}
@ INVTYPE_THROWN
Definition ItemTemplate.h:281
@ EQUIPMENT_SLOT_RANGED
Definition Player.h:688
@ SPELL_ATTR6_DO_NOT_CONSUME_RESOURCES
Definition SharedDefines.h:620
@ CONFIG_ENABLE_INFINITEAMMO
Definition WorldConfig.h:145
uint32 GetMaxStackCount() const
Definition Item.h:274
void DurabilityPointLossForEquipSlot(EquipmentSlots slot)
Definition Player.cpp:4853

References CONFIG_ENABLE_INFINITEAMMO, Player::DestroyItemCount(), Player::DurabilityPointLossForEquipSlot(), EQUIPMENT_SLOT_RANGED, Item::GetMaxStackCount(), Item::GetTemplate(), Object::GetUInt32Value(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), ItemTemplate::InventoryType, INVTYPE_THROWN, Item::IsBroken(), Object::IsPlayer(), ITEM_SUBCLASS_WEAPON_WAND, m_attackType, m_caster, m_spellInfo, PLAYER_AMMO_ID, RANGED_ATTACK, SPELL_ATTR6_DO_NOT_CONSUME_RESOURCES, ItemTemplate::SubClass, sWorld, and Object::ToPlayer().

Referenced by handle_immediate(), spell_hun_explosive_shot::HandleFinish(), and HandleLaunchPhase().

◆ TakeCastItem()

void Spell::TakeCastItem ( )
5282{
5283 if (!m_CastItem || !m_caster->IsPlayer())
5284 return;
5285
5286 // not remove cast item at triggered spell (equipping, weapon damage, etc)
5288 return;
5289
5290 ItemTemplate const* proto = m_CastItem->GetTemplate();
5291
5292 if (!proto)
5293 {
5294 // This code is to avoid a crash
5295 // I'm not sure, if this is really an error, but I guess every item needs a prototype
5296 LOG_ERROR("spells", "Cast item has no item prototype {}", m_CastItem->GetGUID().ToString());
5297 return;
5298 }
5299
5300 bool expendable = false;
5301 bool withoutCharges = false;
5302
5303 for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
5304 {
5305 if (proto->Spells[i].SpellId)
5306 {
5307 // item has limited charges
5308 if (proto->Spells[i].SpellCharges)
5309 {
5310 if (proto->Spells[i].SpellCharges < 0)
5311 expendable = true;
5312
5313 int32 charges = m_CastItem->GetSpellCharges(i);
5314
5315 // item has charges left
5316 if (charges)
5317 {
5318 (charges > 0) ? --charges : ++charges; // std::abs(charges) less at 1 after use
5319 if (proto->Stackable == 1)
5320 m_CastItem->SetSpellCharges(i, charges);
5322 }
5323
5324 // all charges used
5325 withoutCharges = (charges == 0);
5326 }
5327 }
5328 }
5329
5330 if (expendable && withoutCharges)
5331 {
5332 uint32 count = 1;
5333 m_caster->ToPlayer()->DestroyItemCount(m_CastItem, count, true);
5334
5335 // prevent crash at access to deleted m_targets.GetItemTarget
5337 m_targets.SetItemTarget(nullptr);
5338
5339 m_CastItem = nullptr;
5341 }
5342}
void SetSpellCharges(uint8 index, int32 value)
Definition Item.h:318
int32 Stackable
Definition ItemTemplate.h:645

References ObjectGuid::Clear(), Player::DestroyItemCount(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), Item::GetSpellCharges(), Item::GetTemplate(), HasTriggeredCastFlag(), Object::IsPlayer(), ITEM_CHANGED, LOG_ERROR, m_caster, m_CastItem, m_castItemGUID, m_targets, MAX_ITEM_PROTO_SPELLS, SpellCastTargets::SetItemTarget(), Item::SetSpellCharges(), Item::SetState(), _Spell::SpellCharges, _Spell::SpellId, ItemTemplate::Spells, ItemTemplate::Stackable, Object::ToPlayer(), ObjectGuid::ToString(), and TRIGGERED_IGNORE_CAST_ITEM.

Referenced by _cast(), and handle_immediate().

◆ TakePower()

void Spell::TakePower ( )
5345{
5347 return;
5348
5349 //Don't take power if the spell is cast while .cheat power is enabled.
5350 if (m_caster->IsPlayer())
5352 return;
5353
5355 bool hit = true;
5356 if (m_caster->IsPlayer())
5357 {
5359 if (ObjectGuid targetGUID = m_targets.GetUnitTargetGUID())
5360 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5361 if (ihit->targetGUID == targetGUID)
5362 {
5363 if (ihit->missCondition != SPELL_MISS_NONE && ihit->missCondition != SPELL_MISS_BLOCK && ihit->missCondition != SPELL_MISS_ABSORB && ihit->missCondition != SPELL_MISS_REFLECT)
5364 {
5365 hit = false;
5366 //lower spell cost on fail (by talent aura)
5367 if (Player* modOwner = m_caster->ToPlayer()->GetSpellModOwner())
5368 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, m_powerCost, this);
5369 }
5370 break;
5371 }
5372 }
5373
5374 if (PowerType == POWER_RUNE)
5375 {
5376 TakeRunePower(hit);
5377 return;
5378 }
5379
5380 if (!m_powerCost)
5381 return;
5382
5383 // health as power used
5384 if (PowerType == POWER_HEALTH)
5385 {
5387 return;
5388 }
5389
5390 if (PowerType >= MAX_POWERS)
5391 {
5392 LOG_ERROR("spells", "Spell::TakePower: Unknown power type '{}'", PowerType);
5393 return;
5394 }
5395
5396 if (hit)
5398 else
5400
5401 // Set the five second timer
5402 if (PowerType == POWER_MANA && m_powerCost > 0)
5403 {
5405 }
5406}
@ SPELL_MISS_ABSORB
Definition SharedDefines.h:1540
@ SPELLMOD_SPELL_COST_REFUND_ON_FAIL
Definition SpellDefines.h:106
void TakeRunePower(bool didHit)
Definition Spell.cpp:5492
int32 ModifyHealth(int32 val)
Definition Unit.cpp:14192
void SetLastManaUse(uint32 spellCastTime)
Definition Unit.h:1077

References CHEAT_POWER, Player::GetCommandStatus(), GameTime::GetGameTimeMS(), Unit::GetSpellModOwner(), SpellCastTargets::GetUnitTargetGUID(), SpellInfo::Id, irand(), Object::IsPlayer(), LOG_ERROR, m_caster, m_CastItem, m_powerCost, m_spellInfo, m_targets, m_triggeredByAuraSpell, m_UniqueTargetInfo, MAX_POWERS, Unit::ModifyHealth(), Unit::ModifyPower(), POWER_ENERGY, POWER_HEALTH, POWER_MANA, POWER_RAGE, POWER_RUNE, POWER_RUNIC_POWER, SpellInfo::PowerType, Unit::SetLastManaUse(), SPELL_MISS_ABSORB, SPELL_MISS_BLOCK, SPELL_MISS_NONE, SPELL_MISS_REFLECT, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, TakeRunePower(), and Object::ToPlayer().

Referenced by _cast().

◆ TakeReagents()

void Spell::TakeReagents ( )
5562{
5563 if (!m_caster->IsPlayer())
5564 return;
5565
5566 ItemTemplate const* castItemTemplate = m_CastItem ? m_CastItem->GetTemplate() : nullptr;
5567
5568 // do not take reagents for these item casts
5569 if (castItemTemplate && castItemTemplate->HasFlag(ITEM_FLAG_NO_REAGENT_COST))
5570 return;
5571
5572 Player* p_caster = m_caster->ToPlayer();
5573 if (p_caster->CanNoReagentCast(m_spellInfo))
5574 return;
5575
5576 for (uint32 x = 0; x < MAX_SPELL_REAGENTS; ++x)
5577 {
5578 if (m_spellInfo->Reagent[x] <= 0)
5579 continue;
5580
5581 uint32 itemid = m_spellInfo->Reagent[x];
5582 uint32 itemcount = m_spellInfo->ReagentCount[x];
5583
5584 // if CastItem is also spell reagent
5585 if (castItemTemplate && castItemTemplate->ItemId == itemid)
5586 {
5587 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
5588 {
5589 // CastItem will be used up and does not count as reagent
5590 int32 charges = m_CastItem->GetSpellCharges(s);
5591 if (castItemTemplate->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
5592 {
5593 ++itemcount;
5594 break;
5595 }
5596 }
5597
5598 m_CastItem = nullptr;
5600 }
5601
5602 // if GetItemTarget is also spell reagent
5603 if (m_targets.GetItemTargetEntry() == itemid)
5604 m_targets.SetItemTarget(nullptr);
5605
5606 p_caster->DestroyItemCount(itemid, itemcount, true);
5607 }
5608}
uint32 ItemId
Definition ItemTemplate.h:620

References Player::CanNoReagentCast(), ObjectGuid::Clear(), Player::DestroyItemCount(), SpellCastTargets::GetItemTargetEntry(), Item::GetSpellCharges(), Item::GetTemplate(), ItemTemplate::HasFlag(), Object::IsPlayer(), ITEM_FLAG_NO_REAGENT_COST, ItemTemplate::ItemId, m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, MAX_ITEM_PROTO_SPELLS, MAX_SPELL_REAGENTS, SpellInfo::Reagent, SpellInfo::ReagentCount, SpellCastTargets::SetItemTarget(), _Spell::SpellCharges, ItemTemplate::Spells, and Object::ToPlayer().

Referenced by _cast().

◆ TakeRunePower()

void Spell::TakeRunePower ( bool  didHit)
5493{
5495 return;
5496
5497 SpellRuneCostEntry const* runeCostData = sSpellRuneCostStore.LookupEntry(m_spellInfo->RuneCostID);
5498 if (!runeCostData || (runeCostData->NoRuneCost() && runeCostData->NoRunicPowerGain()))
5499 return;
5500
5501 Player* player = m_caster->ToPlayer();
5502 m_runesState = player->GetRunesState(); // store previous state
5503
5504 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5505
5506 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5507 {
5508 runeCost[i] = runeCostData->RuneCost[i];
5509 if (Player* modOwner = m_caster->GetSpellModOwner())
5510 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5511 }
5512
5513 runeCost[RUNE_DEATH] = 0; // calculated later
5514
5515 for (uint32 i = 0; i < MAX_RUNES; ++i)
5516 {
5517 RuneType rune = player->GetCurrentRune(i);
5518 if (!player->GetRuneCooldown(i) && runeCost[rune] > 0)
5519 {
5520 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5521 player->SetLastUsedRune(rune);
5522 runeCost[rune]--;
5523 }
5524 }
5525
5526 // Xinef: firstly consume death runes of base type
5527 // Xinef: in second loop consume all available
5528 for (uint8 loop = 0; loop < 2; ++loop)
5529 {
5530 runeCost[RUNE_DEATH] = runeCost[RUNE_BLOOD] + runeCost[RUNE_UNHOLY] + runeCost[RUNE_FROST];
5531 if (runeCost[RUNE_DEATH] > 0)
5532 {
5533 for (uint8 i = 0; i < MAX_RUNES; ++i)
5534 {
5535 RuneType rune = player->GetCurrentRune(i);
5536 if (!player->GetRuneCooldown(i) && rune == RUNE_DEATH && (loop ? true : (runeCost[player->GetBaseRune(i)] > 0)))
5537 {
5538 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5539 player->SetLastUsedRune(rune);
5540 runeCost[rune]--;
5541 if (!loop)
5542 runeCost[player->GetBaseRune(i)]--;
5543
5544 // keep Death Rune type if missed
5545 if (didHit)
5546 player->RestoreBaseRune(i);
5547
5548 if (runeCost[RUNE_DEATH] == 0)
5549 break;
5550 }
5551 }
5552 }
5553 }
5554
5555 // you can gain some runic power when use runes
5556 if (didHit)
5557 if (int32 rp = int32(runeCostData->runePowerGain * sWorld->getRate(RATE_POWER_RUNICPOWER_INCOME)))
5558 player->ModifyPower(POWER_RUNIC_POWER, int32(rp));
5559}
@ RUNE_UNHOLY
Definition Player.h:405
@ RUNE_BLOOD
Definition Player.h:404
@ RUNE_MISS_COOLDOWN
Definition Player.h:399
@ RATE_POWER_RUNICPOWER_INCOME
Definition WorldConfig.h:392
void SetLastUsedRune(RuneType type)
Definition Player.h:2523
uint32 GetRuneBaseCooldown(uint8 index, bool skipGrace)
Definition Player.cpp:13393
void RestoreBaseRune(uint8 index)
Definition Player.cpp:13422
bool NoRunicPowerGain() const
Definition DBCStructure.h:1812
uint32 runePowerGain
Definition DBCStructure.h:1809

References CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, Player::GetBaseRune(), Player::GetCurrentRune(), Player::GetRuneBaseCooldown(), Player::GetRuneCooldown(), Player::GetRunesState(), Unit::GetSpellModOwner(), SpellInfo::Id, Unit::IsClass(), Object::IsPlayer(), m_caster, m_runesState, m_spellInfo, MAX_RUNES, Unit::ModifyPower(), SpellRuneCostEntry::NoRuneCost(), SpellRuneCostEntry::NoRunicPowerGain(), NUM_RUNE_TYPES, POWER_RUNIC_POWER, RATE_POWER_RUNICPOWER_INCOME, Player::RestoreBaseRune(), RUNE_BLOOD, RUNE_DEATH, RUNE_FROST, RUNE_MISS_COOLDOWN, RUNE_UNHOLY, SpellRuneCostEntry::RuneCost, SpellInfo::RuneCostID, SpellRuneCostEntry::runePowerGain, Player::SetLastUsedRune(), Player::SetRuneCooldown(), SPELLMOD_COST, sSpellRuneCostStore, sWorld, and Object::ToPlayer().

Referenced by TakePower().

◆ TriggerGlobalCooldown()

void Spell::TriggerGlobalCooldown ( )
protected
8896{
8898 if (!gcd)
8899 {
8900 // Xinef: fix for charmed pet spells with no cooldown info
8902 gcd = MIN_GCD;
8903 else
8904 return;
8905 }
8906
8907 if (m_caster->IsPlayer())
8909 return;
8910
8911 // Global cooldown can't leave range 1..1.5 secs
8912 // There are some spells (mostly not casted directly by player) that have < 1 sec and > 1.5 sec global cooldowns
8913 // but as tests show are not affected by any spell mods.
8915 {
8916 // gcd modifier auras are applied only to own spells and only players have such mods
8917 if (m_caster->IsPlayer())
8919
8920 // Apply haste rating
8923 {
8924 gcd = int32(float(gcd) * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
8925 }
8926
8927 if (gcd < MIN_GCD)
8928 gcd = MIN_GCD;
8929 else if (gcd > MAX_GCD)
8930 gcd = MAX_GCD;
8931 }
8932
8933 // Only players or controlled units have global cooldown
8934 if (m_caster->GetCharmInfo())
8936 else if (m_caster->IsPlayer())
8938}
@ SPELLMOD_GLOBAL_COOLDOWN
Definition SpellDefines.h:97
@ MIN_GCD
Definition Spell.cpp:8880
@ MAX_GCD
Definition Spell.cpp:8881
void AddGlobalCooldown(SpellInfo const *spellInfo, uint32 gcd)
Definition CharmInfo.cpp:419

References GlobalCooldownMgr::AddGlobalCooldown(), Player::ApplySpellMod(), SpellInfo::CategoryRecoveryTime, CHEAT_COOLDOWN, SpellInfo::DmgClass, Unit::GetCharmInfo(), Player::GetCommandStatus(), Object::GetFloatValue(), Player::GetGlobalCooldownMgr(), CharmInfo::GetGlobalCooldownMgr(), SpellInfo::HasAttribute(), SpellInfo::Id, Object::IsPlayer(), m_caster, m_spellInfo, MAX_GCD, MIN_GCD, SpellInfo::RecoveryTime, SPELL_ATTR0_IS_ABILITY, SPELL_ATTR0_USES_RANGED_SLOT, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELLMOD_GLOBAL_COOLDOWN, SpellInfo::StartRecoveryCategory, SpellInfo::StartRecoveryTime, Object::ToPlayer(), and UNIT_MOD_CAST_SPEED.

Referenced by prepare().

◆ update()

void Spell::update ( uint32  difftime)
4421{
4422 // update pointers based at it's GUIDs
4423 if (!UpdatePointers())
4424 {
4425 // cancel the spell if UpdatePointers() returned false, something wrong happened there
4426 cancel();
4427 return;
4428 }
4429
4431 {
4432 LOG_DEBUG("spells.aura", "Spell {} is cancelled due to removal of target.", m_spellInfo->Id);
4433 cancel();
4434 return;
4435 }
4436
4437 // check if the player caster has moved before the spell finished
4438 // xinef: added preparing state (real cast, skip channels as they have other flags for this)
4439 if ((m_caster->IsPlayer() && m_timer != 0) &&
4442 {
4443 // don't cancel for melee, autorepeat, triggered and instant spells
4445 cancel(true);
4446 }
4447
4448 switch (m_spellState)
4449 {
4451 {
4452 if (m_timer > 0)
4453 {
4454 if (difftime >= (uint32)m_timer)
4455 m_timer = 0;
4456 else
4457 m_timer -= difftime;
4458 }
4459
4460 if (m_timer == 0 && !IsNextMeleeSwingSpell() && !IsAutoRepeat())
4461 // don't CheckCast for instant spells - done in spell::prepare, skip duplicate checks, needed for range checks for example
4462 cast(!m_casttime);
4463 break;
4464 }
4466 {
4467 if (m_timer)
4468 {
4469 if (m_timer > 0)
4470 {
4471 if (difftime >= (uint32)m_timer)
4472 m_timer = 0;
4473 else
4474 m_timer -= difftime;
4475 }
4476 }
4477
4478 if (m_timer == 0)
4479 {
4481
4482 finish();
4483
4484 // We call the hook here instead of in Spell::finish because we only want to call it for completed channeling. Everything else is handled by interrupts
4485 if (Creature* creatureCaster = m_caster->ToCreature())
4486 if (creatureCaster->IsAIEnabled)
4487 creatureCaster->AI()->OnSpellCastFinished(m_spellInfo, SPELL_FINISHED_CHANNELING_COMPLETE);
4488 }
4489 // Xinef: Dont update channeled target list on last tick, allow auras to update duration properly
4490 // Xinef: Added this strange check because of diffrent update routines for players / creatures
4491 // Xinef: If creature gets new aura in 800ms and in 840ms its updated with diff 270, not 40 is removed from duration but 270
4492 // Xinef: so the aura can be removed in different updates for all units
4493 else if ((m_timer < 0 || m_timer > 300) && !UpdateChanneledTargetList())
4494 {
4495 LOG_DEBUG("spells.aura", "Channeled spell {} is removed due to lack of targets", m_spellInfo->Id);
4497 finish();
4498 }
4499 break;
4500 }
4501 default:
4502 break;
4503 }
4504}
@ SPELL_FINISHED_CHANNELING_COMPLETE
Definition Spell.h:99
bool UpdateChanneledTargetList()
Definition Spell.cpp:3394

References cancel(), cast(), SpellInfo::Effects, finish(), SpellCastTargets::GetUnitTarget(), SpellCastTargets::GetUnitTargetGUID(), Unit::HasUnitMovementFlag(), SpellInfo::Id, SpellInfo::InterruptFlags, IsAutoRepeat(), Unit::isMoving(), IsNextMeleeSwingSpell(), Object::IsPlayer(), IsTriggered(), LOG_DEBUG, m_caster, m_casttime, m_spellInfo, m_spellState, m_targets, m_timer, MOVEMENTFLAG_FALLING_FAR, SendChannelUpdate(), SPELL_EFFECT_STUCK, SPELL_FINISHED_CHANNELING_COMPLETE, SPELL_INTERRUPT_FLAG_MOVEMENT, SPELL_STATE_CASTING, SPELL_STATE_PREPARING, Object::ToCreature(), UpdateChanneledTargetList(), and UpdatePointers().

Referenced by SpellEvent::Execute().

◆ UpdateChanneledTargetList()

bool Spell::UpdateChanneledTargetList ( )
protected
3395{
3396 // Not need check return true
3398 return true;
3399
3400 uint8 channelTargetEffectMask = m_channelTargetEffectMask;
3401 uint8 channelAuraMask = 0;
3402 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3404 channelAuraMask |= 1 << i;
3405
3406 channelAuraMask &= channelTargetEffectMask;
3407
3408 float range = 0;
3409 if (channelAuraMask)
3410 {
3412 if (range == 0)
3413 for(int i = EFFECT_0; i <= EFFECT_2; ++i)
3414 if (channelAuraMask & (1 << i) && m_spellInfo->Effects[i].RadiusEntry)
3415 {
3416 range = m_spellInfo->Effects[i].CalcRadius(nullptr, nullptr);
3417 break;
3418 }
3419
3420 if (Player* modOwner = m_caster->GetSpellModOwner())
3421 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
3422
3423 // xinef: add little tolerance level
3424 range += std::min(3.0f, range * 0.1f); // 10% but no more than 3yd
3425 }
3426
3427 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3428 {
3429 if (ihit->missCondition == SPELL_MISS_NONE && (channelTargetEffectMask & ihit->effectMask))
3430 {
3431 Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
3432
3433 if (!unit)
3434 continue;
3435
3436 if (IsValidDeadOrAliveTarget(unit))
3437 {
3438 if (channelAuraMask & ihit->effectMask)
3439 {
3441 {
3442 if (m_caster != unit)
3443 {
3444 if (!m_caster->IsWithinDistInMap(unit, range))
3445 {
3446 ihit->effectMask &= ~aurApp->GetEffectMask();
3447 unit->RemoveAura(aurApp);
3448 continue;
3449 }
3450 // Xinef: Update Orientation server side (non players wont sent appropriate packets)
3453 }
3454 }
3455 else // aura is dispelled
3456 continue;
3457 }
3458
3459 channelTargetEffectMask &= ~ihit->effectMask; // remove from need alive mask effect that have alive target
3460 }
3461 }
3462 }
3463
3464 // Xinef: not all effects are covered, remove applications from all targets
3465 if (channelTargetEffectMask != 0)
3466 {
3467 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3468 if (ihit->missCondition == SPELL_MISS_NONE && (channelAuraMask & ihit->effectMask))
3469 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3470 if (IsValidDeadOrAliveTarget(unit))
3472 {
3473 ihit->effectMask &= ~aurApp->GetEffectMask();
3474 unit->RemoveAura(aurApp);
3475 }
3476 }
3477
3478 // is all effects from m_needAliveTargetMask have alive targets
3479 return channelTargetEffectMask == 0;
3480}
@ SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL
Definition SharedDefines.h:444
bool IsValidDeadOrAliveTarget(Unit const *target) const
Definition Spell.cpp:8268
AuraApplication * GetAuraApplication(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraApplication *except=nullptr) const
Definition Unit.cpp:5627
void UpdateOrientation(float orientation)
Only server-side orientation update, does not broadcast to client.
Definition Unit.cpp:19893
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool useBoundingRadius=true) const
Definition Object.cpp:1326

References EFFECT_0, EFFECT_2, SpellInfo::Effects, Position::GetAngle(), Unit::GetAuraApplication(), Object::GetGUID(), SpellInfo::GetMaxRange(), Unit::GetSpellModOwner(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, Object::IsPlayer(), SpellInfo::IsPositive(), IsValidDeadOrAliveTarget(), WorldObject::IsWithinDistInMap(), m_caster, m_channelTargetEffectMask, m_originalCasterGUID, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, Unit::RemoveAura(), SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL, SPELL_EFFECT_APPLY_AURA, SPELL_MISS_NONE, SPELLMOD_RANGE, and Unit::UpdateOrientation().

Referenced by update().

◆ UpdatePointers()

bool Spell::UpdatePointers ( )
7907{
7910 else
7911 {
7914 m_originalCaster = nullptr;
7915 }
7916
7918 {
7920 // cast item not found, somehow the item is no longer where we expected
7921 if (!m_CastItem)
7922 return false;
7923 }
7924 else
7925 m_CastItem = nullptr;
7926
7928
7929 // further actions done only for dest targets
7930 if (!m_targets.HasDst())
7931 return true;
7932
7933 // cache last transport
7934 WorldObject* transport = nullptr;
7935
7936 // update effect destinations (in case of moved transport dest target)
7937 for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
7938 {
7939 SpellDestination& dest = m_destTargets[effIndex];
7940 if (!dest._transportGUID)
7941 continue;
7942
7943 if (!transport || transport->GetGUID() != dest._transportGUID)
7945
7946 if (transport)
7947 {
7948 dest._position.Relocate(transport);
7950 }
7951 }
7952
7953 return true;
7954}
void Update(Unit *caster)
Definition Spell.cpp:479
WorldObject * GetWorldObject(WorldObject const &, ObjectGuid const guid)
Definition ObjectAccessor.cpp:115
void RelocateOffset(const Position &offset)
Definition Position.cpp:59
Position _transportOffset
Definition Spell.h:114
ObjectGuid _transportGUID
Definition Spell.h:113

References SpellDestination::_position, SpellDestination::_transportGUID, SpellDestination::_transportOffset, Object::GetGUID(), Player::GetItemByGuid(), ObjectAccessor::GetUnit(), ObjectAccessor::GetWorldObject(), SpellCastTargets::HasDst(), Object::IsInWorld(), Object::IsPlayer(), m_caster, m_CastItem, m_castItemGUID, m_destTargets, m_originalCaster, m_originalCasterGUID, m_targets, MAX_SPELL_EFFECTS, Position::Relocate(), Position::RelocateOffset(), Object::ToPlayer(), and SpellCastTargets::Update().

Referenced by _cast(), handle_delayed(), and update().

◆ WriteAmmoToPacket()

void Spell::WriteAmmoToPacket ( WorldPacket data)
4958{
4959 uint32 ammoInventoryType = 0;
4960 uint32 ammoDisplayID = 0;
4961
4962 if (m_caster->IsPlayer())
4963 {
4965 if (pItem)
4966 {
4967 ammoInventoryType = pItem->GetTemplate()->InventoryType;
4968 if (ammoInventoryType == INVTYPE_THROWN)
4969 ammoDisplayID = pItem->GetTemplate()->DisplayInfoID;
4970 else
4971 {
4973 if (ammoID)
4974 {
4975 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(ammoID);
4976 if (pProto)
4977 {
4978 ammoDisplayID = pProto->DisplayInfoID;
4979 ammoInventoryType = pProto->InventoryType;
4980 }
4981 }
4982 else if (m_caster->HasAura(46699)) // Requires No Ammo
4983 {
4984 ammoDisplayID = 5996; // normal arrow
4985 ammoInventoryType = INVTYPE_AMMO;
4986 }
4987 }
4988 }
4989 }
4990 else
4991 {
4992 uint32 nonRangedAmmoDisplayID = 0;
4993 uint32 nonRangedAmmoInventoryType = 0;
4994 for (uint8 i = 0; i < 3; ++i)
4995 {
4997 {
4998 if (ItemEntry const* itemEntry = sItemStore.LookupEntry(item_id))
4999 {
5000 if (itemEntry->ClassID == ITEM_CLASS_WEAPON)
5001 {
5002 switch (itemEntry->SubclassID)
5003 {
5005 ammoDisplayID = itemEntry->DisplayInfoID;
5006 ammoInventoryType = itemEntry->InventoryType;
5007 break;
5010 ammoDisplayID = 5996; // is this need fixing?
5011 ammoInventoryType = INVTYPE_AMMO;
5012 break;
5014 ammoDisplayID = 5998; // is this need fixing?
5015 ammoInventoryType = INVTYPE_AMMO;
5016 break;
5017 default:
5018 nonRangedAmmoDisplayID = itemEntry->DisplayInfoID;
5019 nonRangedAmmoInventoryType = itemEntry->InventoryType;
5020 break;
5021 }
5022
5023 if (ammoDisplayID)
5024 break;
5025 }
5026 }
5027 }
5028 }
5029
5030 if (!ammoDisplayID && !ammoInventoryType)
5031 {
5032 ammoDisplayID = nonRangedAmmoDisplayID;
5033 ammoInventoryType = nonRangedAmmoInventoryType;
5034 }
5035 }
5036
5037 *data << uint32(ammoDisplayID);
5038 *data << uint32(ammoInventoryType);
5039}
DBCStorage< ItemEntry > sItemStore(Itemfmt)
@ INVTYPE_AMMO
Definition ItemTemplate.h:280
@ UNIT_VIRTUAL_ITEM_SLOT_ID
Definition UpdateFields.h:116
Definition DBCStructure.h:1141
uint32 DisplayInfoID
Definition ItemTemplate.h:625

References ItemTemplate::DisplayInfoID, Item::GetTemplate(), Object::GetUInt32Value(), Player::GetWeaponForAttack(), Unit::HasAura(), ItemTemplate::InventoryType, INVTYPE_AMMO, INVTYPE_THROWN, Object::IsPlayer(), ITEM_CLASS_WEAPON, ITEM_SUBCLASS_WEAPON_BOW, ITEM_SUBCLASS_WEAPON_CROSSBOW, ITEM_SUBCLASS_WEAPON_GUN, ITEM_SUBCLASS_WEAPON_THROWN, m_caster, PLAYER_AMMO_ID, RANGED_ATTACK, sItemStore, sObjectMgr, Object::ToPlayer(), and UNIT_VIRTUAL_ITEM_SLOT_ID.

Referenced by SendSpellGo(), and SendSpellStart().

◆ WriteCastResultInfo()

void Spell::WriteCastResultInfo ( WorldPacket data,
Player caster,
SpellInfo const *  spellInfo,
uint8  castCount,
SpellCastResult  result,
SpellCustomErrors  customError 
)
static
4594{
4595 data << uint8(castCount); // single cast or multi 2.3 (0/1)
4596 data << uint32(spellInfo->Id);
4597 data << uint8(result); // problem
4598 switch (result)
4599 {
4601 data << uint32(spellInfo->RequiresSpellFocus); // SpellFocusObject.dbc id
4602 break;
4603 case SPELL_FAILED_REQUIRES_AREA: // AreaTable.dbc id
4604 // hardcode areas limitation case
4605 switch (spellInfo->Id)
4606 {
4607 case 41617: // Cenarion Mana Salve
4608 case 41619: // Cenarion Healing Salve
4609 data << uint32(3905);
4610 break;
4611 case 41618: // Bottled Nethergon Energy
4612 case 41620: // Bottled Nethergon Vapor
4613 data << uint32(3842);
4614 break;
4615 case 45373: // Bloodberry Elixir
4616 data << uint32(4075);
4617 break;
4618 default: // default case (don't must be)
4619 data << uint32(0);
4620 break;
4621 }
4622 break;
4624 if (spellInfo->Totem[0])
4625 data << uint32(spellInfo->Totem[0]);
4626 if (spellInfo->Totem[1])
4627 data << uint32(spellInfo->Totem[1]);
4628 break;
4630 if (spellInfo->TotemCategory[0])
4631 data << uint32(spellInfo->TotemCategory[0]);
4632 if (spellInfo->TotemCategory[1])
4633 data << uint32(spellInfo->TotemCategory[1]);
4634 break;
4638 data << uint32(spellInfo->EquippedItemClass);
4639 data << uint32(spellInfo->EquippedItemSubClassMask);
4640 break;
4642 {
4643 uint32 item = 0;
4644 for (int8 eff = 0; eff < MAX_SPELL_EFFECTS; eff++)
4645 if (spellInfo->Effects[eff].ItemType)
4646 item = spellInfo->Effects[eff].ItemType;
4647 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item);
4648 if (proto && proto->ItemLimitCategory)
4649 data << uint32(proto->ItemLimitCategory);
4650 break;
4651 }
4653 data << uint32(customError);
4654 break;
4656 {
4657 uint32 missingItem = 0;
4658 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
4659 {
4660 if (spellInfo->Reagent[i] <= 0)
4661 continue;
4662
4663 uint32 itemid = spellInfo->Reagent[i];
4664 uint32 itemcount = spellInfo->ReagentCount[i];
4665
4666 if (!caster->HasItemCount(itemid, itemcount))
4667 {
4668 missingItem = itemid;
4669 break;
4670 }
4671 }
4672
4673 data << uint32(missingItem); // first missing item
4674 break;
4675 }
4677 data << uint32(spellInfo->Mechanic);
4678 break;
4680 data << uint32(spellInfo->EquippedItemSubClassMask);
4681 break;
4683 data << uint32(0); // Item entry
4684 data << uint32(0); // Count
4685 break;
4687 data << uint32(0); // SkillLine.dbc Id
4688 data << uint32(0); // Amount
4689 break;
4691 data << uint32(0); // Skill level
4692 break;
4693 default:
4694 break;
4695 }
4696}
@ SPELL_FAILED_NEED_EXOTIC_AMMO
Definition SharedDefines.h:1014
@ SPELL_FAILED_FISHING_TOO_LOW
Definition SharedDefines.h:1141
@ SPELL_FAILED_MIN_SKILL
Definition SharedDefines.h:1110
@ SPELL_FAILED_PREVENTED_BY_MECHANIC
Definition SharedDefines.h:1107
@ SPELL_FAILED_REQUIRES_AREA
Definition SharedDefines.h:1061

References SpellInfo::Effects, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, Player::HasItemCount(), SpellInfo::Id, ItemTemplate::ItemLimitCategory, MAX_SPELL_EFFECTS, MAX_SPELL_REAGENTS, SpellInfo::Mechanic, SpellInfo::Reagent, SpellInfo::ReagentCount, SpellInfo::RequiresSpellFocus, sObjectMgr, SPELL_FAILED_CUSTOM_ERROR, SPELL_FAILED_EQUIPPED_ITEM_CLASS, SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND, SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND, SPELL_FAILED_FISHING_TOO_LOW, SPELL_FAILED_MIN_SKILL, SPELL_FAILED_NEED_EXOTIC_AMMO, SPELL_FAILED_NEED_MORE_ITEMS, SPELL_FAILED_PREVENTED_BY_MECHANIC, SPELL_FAILED_REAGENTS, SPELL_FAILED_REQUIRES_AREA, SPELL_FAILED_REQUIRES_SPELL_FOCUS, SPELL_FAILED_TOO_MANY_OF_ITEM, SPELL_FAILED_TOTEM_CATEGORY, SPELL_FAILED_TOTEMS, SpellInfo::Totem, and SpellInfo::TotemCategory.

Referenced by SendCastResult(), and SendPetCastResult().

◆ WriteSpellGoTargets()

void Spell::WriteSpellGoTargets ( WorldPacket data)

Writes miss and hit targets for a SMSG_SPELL_GO packet.

5043{
5044 // This function also fill data for channeled spells:
5045 // m_needAliveTargetMask req for stop channelig if one target die
5046 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5047 {
5048 if ((*ihit).effectMask == 0) // No effect apply - all immuned add state
5049 // possibly SPELL_MISS_IMMUNE2 for this??
5050 ihit->missCondition = SPELL_MISS_IMMUNE2;
5051 }
5052
5053 // Hit and miss target counts are both uint8, that limits us to 255 targets for each
5054 // sending more than 255 targets crashes the client (since count sent would be wrong)
5055 // Spells like 40647 (with a huge radius) can easily reach this limit (spell might need
5056 // target conditions but we still need to limit the number of targets sent and keeping
5057 // correct count for both hit and miss).
5058
5059 uint32 hit = 0;
5060 std::size_t hitPos = data->wpos();
5061 *data << (uint8)0; // placeholder
5062 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && hit < 255; ++ihit)
5063 {
5064 if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits
5065 {
5066 *data << ihit->targetGUID;
5067 // Xinef: No channeled spell checked, no anything
5068 //m_channelTargetEffectMask |=ihit->effectMask;
5069 ++hit;
5070 }
5071 }
5072
5073 for (std::list<GOTargetInfo>::const_iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end() && hit < 255; ++ighit)
5074 {
5075 *data << ighit->targetGUID; // Always hits
5076 ++hit;
5077 }
5078
5079 uint32 miss = 0;
5080 std::size_t missPos = data->wpos();
5081 *data << (uint8)0; // placeholder
5082 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && miss < 255; ++ihit)
5083 {
5084 if (ihit->missCondition != SPELL_MISS_NONE) // Add only miss
5085 {
5086 *data << ihit->targetGUID;
5087 *data << uint8(ihit->missCondition);
5088 if (ihit->missCondition == SPELL_MISS_REFLECT)
5089 *data << uint8(ihit->reflectResult);
5090 ++miss;
5091 }
5092 }
5093 // Reset m_needAliveTargetMask for non channeled spell
5094 // Xinef: Why do we reset something that is not set??????
5095 //if (!m_spellInfo->IsChanneled())
5096 // m_channelTargetEffectMask = 0;
5097
5098 data->put<uint8>(hitPos, (uint8)hit);
5099 data->put<uint8>(missPos, (uint8)miss);
5100}
std::size_t wpos() const
Definition ByteBuffer.h:330
void put(std::size_t pos, T value)
Definition ByteBuffer.h:137

References m_UniqueGOTargetInfo, m_UniqueTargetInfo, ByteBuffer::put(), SPELL_MISS_IMMUNE2, SPELL_MISS_NONE, SPELL_MISS_REFLECT, and ByteBuffer::wpos().

Referenced by SendSpellGo().

Friends And Related Symbol Documentation

◆ SpellScript

friend class SpellScript
friend

◆ Unit::SetCurrentCastedSpell

void Unit::SetCurrentCastedSpell ( Spell pSpell)
friend

Member Data Documentation

◆ _scriptsLoaded

bool Spell::_scriptsLoaded
protected

Referenced by LoadScripts(), and Spell().

◆ _spellEvent

SpellEvent* Spell::_spellEvent
protected

◆ _spellTargetsSelected

bool Spell::_spellTargetsSelected
protected

Referenced by _cast(), prepare(), and Spell().

◆ _triggeredCastFlags

TriggerCastFlags Spell::_triggeredCastFlags
protected

◆ damage

◆ destTarget

◆ effectHandleMode

SpellEffectHandleMode Spell::effectHandleMode
protected

Referenced by EffectActivateObject(), EffectActivateRune(), EffectActivateSpec(), EffectAddComboPoints(), EffectAddExtraAttacks(), EffectAddFarsight(), EffectAddHonor(), EffectApplyAreaAura(), EffectApplyAura(), EffectApplyGlyph(), EffectBind(), EffectBlock(), EffectCastButtons(), EffectCharge(), EffectChargeDest(), EffectCreateItem(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDestroyAllTotems(), EffectDiscoverTaxi(), EffectDisEnchant(), EffectDismissPet(), EffectDispel(), EffectDispelMechanic(), EffectDistract(), EffectDualWield(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectDamage(), EffectGameObjectRepair(), EffectGameObjectSetDestructionState(), EffectHeal(), EffectHealMaxHealth(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInebriate(), EffectInstaKill(), EffectInterruptCast(), EffectJump(), EffectJumpDest(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectMilling(), EffectModifyThreatPercent(), EffectOpenLock(), EffectParry(), EffectPersistentAA(), EffectPickPocket(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectProspecting(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectRemoveAura(), EffectRenamePet(), EffectReputation(), EffectResurrect(), EffectResurrectNew(), EffectResurrectPet(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSendTaxi(), EffectSkill(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectSpecCount(), EffectSpiritHeal(), EffectStealBeneficialBuff(), EffectStuck(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTradeSkill(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), HandleEffects(), and Spell().

◆ focusObject

◆ gameObjTarget

◆ itemTarget

◆ m_appliedMods

◆ m_applyMultiplierMask

uint8 Spell::m_applyMultiplierMask
protected

◆ m_attackType

◆ m_auraScaleMask

uint8 Spell::m_auraScaleMask
protected

◆ m_autoRepeat

bool Spell::m_autoRepeat
protected

◆ m_canReflect

bool Spell::m_canReflect
protected

Referenced by AddUnitTarget(), and Spell().

◆ m_cast_count

◆ m_caster

Unit* const Spell::m_caster
protected

Referenced by _cast(), _handle_finish_phase(), AddGOTarget(), AddUnitTarget(), CalculateDelayMomentForDst(), CalculateJumpSpeeds(), CalculateSpellDamage(), cancel(), CancelGlobalCooldown(), CanOpenLock(), cast(), CheckCast(), CheckCasterAuras(), CheckDst(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckPower(), CheckRange(), CheckRuneCost(), CheckSpellFocus(), CheckSrc(), Delayed(), DelayedChannel(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoAllEffectOnTarget(), DoCreateItem(), DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EffectActivateObject(), EffectActivateRune(), EffectAddFarsight(), EffectApplyGlyph(), EffectBind(), EffectBlock(), EffectCastButtons(), EffectCharge(), EffectChargeDest(), EffectDestroyAllTotems(), EffectDisEnchant(), EffectDispel(), EffectDispelMechanic(), EffectDuel(), EffectDummy(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectRepair(), EffectHeal(), EffectHealMaxHealth(), EffectHealthLeech(), EffectInstaKill(), EffectJump(), EffectJumpDest(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnSpell(), EffectMilling(), EffectModifyThreatPercent(), EffectOpenLock(), EffectParry(), EffectPersistentAA(), EffectPickPocket(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectProspecting(), EffectPullTowards(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectResurrect(), EffectResurrectNew(), EffectResurrectPet(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectStealBeneficialBuff(), EffectStuck(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTradeSkill(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), finish(), GetCaster(), handle_delayed(), handle_immediate(), HandleLaunchPhase(), HandleThreatSpells(), HasGlobalCooldown(), InitExplicitTargets(), IsChannelActive(), OnSpellLaunch(), prepare(), prepareDataForTriggerSystem(), PrepareTriggersExecutedOnHit(), RecalculateDelayMomentForDst(), SearchAreaTargets(), SearchChainTargets(), SearchNearbyTarget(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTrajTargets(), SendCastResult(), SendChannelStart(), SendChannelUpdate(), SendInterrupted(), SendLogExecute(), SendLoot(), SendPetCastResult(), SendResurrectRequest(), SendSpellCooldown(), SendSpellGo(), SendSpellStart(), Spell(), SummonGuardian(), TakeAmmo(), TakeCastItem(), TakePower(), TakeReagents(), TakeRunePower(), TriggerGlobalCooldown(), update(), UpdateChanneledTargetList(), UpdatePointers(), and WriteAmmoToPacket().

◆ m_CastItem

◆ m_castItemGUID

◆ m_casttime

◆ m_channeledDuration

int32 Spell::m_channeledDuration
protected

◆ m_channelTargetEffectMask

uint8 Spell::m_channelTargetEffectMask
protected

◆ m_comboPointGain

int8 Spell::m_comboPointGain

◆ m_comboTarget

Unit* Spell::m_comboTarget

◆ m_customError

◆ m_damage

◆ m_damageMultipliers

float Spell::m_damageMultipliers[3]
protected

◆ m_delayAtDamageCount

uint8 Spell::m_delayAtDamageCount
protected

Referenced by isDelayableNoMore(), and Spell().

◆ m_delayMoment

◆ m_delayStart

uint64 Spell::m_delayStart
protected

Referenced by GetDelayStart(), SetDelayStart(), and Spell().

◆ m_delayTrajectory

uint64 Spell::m_delayTrajectory
protected

◆ m_destTargets

SpellDestination Spell::m_destTargets[MAX_SPELL_EFFECTS]
protected

◆ m_diminishGroup

DiminishingGroup Spell::m_diminishGroup
protected

◆ m_diminishLevel

DiminishingLevels Spell::m_diminishLevel
protected

◆ m_effectExecuteData

◆ m_executedCurrently

bool Spell::m_executedCurrently
protected

◆ m_glyphIndex

uint32 Spell::m_glyphIndex

◆ m_healing

◆ m_hitTriggerSpells

HitTriggerSpellList Spell::m_hitTriggerSpells
protected

◆ m_immediateHandled

bool Spell::m_immediateHandled
protected

Referenced by _cast(), handle_delayed(), and Spell().

◆ m_loadedScripts

◆ m_needComboPoints

bool Spell::m_needComboPoints
protected

◆ m_originalCaster

◆ m_originalCasterGUID

◆ m_powerCost

◆ m_preCastSpell

uint32 Spell::m_preCastSpell

◆ m_preGeneratedPath

std::unique_ptr<PathGenerator> Spell::m_preGeneratedPath
protected

Referenced by CheckCast(), and EffectCharge().

◆ m_procAttacker

uint32 Spell::m_procAttacker
protected

◆ m_procEx

uint32 Spell::m_procEx
protected

◆ m_procVictim

uint32 Spell::m_procVictim
protected

◆ m_referencedFromCurrentSpell

bool Spell::m_referencedFromCurrentSpell
protected

◆ m_runesState

uint8 Spell::m_runesState
protected

◆ m_selfContainer

Spell** Spell::m_selfContainer
protected

◆ m_skipCheck

bool Spell::m_skipCheck
protected

Referenced by AddUnitTarget(), and Spell().

◆ m_spellAura

◆ m_spellFlags

◆ m_spellInfo

SpellInfo const* const Spell::m_spellInfo

Referenced by _cast(), _handle_finish_phase(), _handle_immediate_phase(), Unit::_UpdateAutoRepeatSpell(), AddGOTarget(), AddItemTarget(), AddUnitTarget(), CalculateDelayMomentForDst(), CalculateJumpSpeeds(), CalculateSpellDamage(), CallScriptDestinationTargetSelectHandlers(), CallScriptEffectHandlers(), CallScriptObjectAreaTargetSelectHandlers(), CallScriptObjectTargetSelectHandlers(), CanAutoCast(), cancel(), CancelGlobalCooldown(), CanExecuteTriggersOnHit(), CanOpenLock(), CheckCast(), CheckCasterAuras(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckPower(), CheckRange(), CheckRuneCost(), CheckScriptEffectImplicitTargets(), CheckSpellFocus(), Delayed(), DelayedChannel(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoAllEffectOnTarget(), DoCreateItem(), DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EffectActivateObject(), EffectActivateRune(), EffectAddFarsight(), EffectAddHonor(), EffectApplyGlyph(), EffectBind(), EffectCastButtons(), EffectCharge(), EffectCreateItem(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDiscoverTaxi(), EffectDisEnchant(), EffectDispel(), EffectDispelMechanic(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectSetDestructionState(), EffectHeal(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInstaKill(), EffectInterruptCast(), EffectJumpDest(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectOpenLock(), EffectPersistentAA(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRemoveAura(), EffectReputation(), EffectResurrectNew(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSendTaxi(), EffectStealBeneficialBuff(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectWeaponDmg(), finish(), GetCurrentContainer(), GetSearcherTypeMask(), GetSpellInfo(), handle_immediate(), WorldSession::HandleCastSpellOpcode(), HandleEffects(), HandleLaunchPhase(), WorldSession::HandlePetCastSpellOpcode(), HandleThreatSpells(), WorldSession::HandleUpdateMissileTrajectory(), HasGlobalCooldown(), InitExplicitTargets(), IsAutoActionResetSpell(), IsNeedSendToClient(), IsNextMeleeSwingSpell(), IsValidDeadOrAliveTarget(), LoadScripts(), OnSpellLaunch(), prepare(), prepareDataForTriggerSystem(), PrepareTriggersExecutedOnHit(), Player::RemoveSpellMods(), Player::RestoreSpellMods(), SearchAreaTargets(), SearchChainTargets(), SearchNearbyTarget(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTrajTargets(), SelectSpellTargets(), SendCastResult(), SendChannelStart(), SendInterrupted(), SendLogExecute(), SendPetCastResult(), SendResurrectRequest(), SendSpellCooldown(), SendSpellGo(), SendSpellStart(), Unit::SetCurrentCastedSpell(), Player::SetSpellModTakingSpell(), SetSpellValue(), Spell(), SummonGuardian(), TakeAmmo(), TakePower(), TakeReagents(), TakeRunePower(), TriggerGlobalCooldown(), update(), PetAI::UpdateAI(), UpdateChanneledTargetList(), Player::UpdatePotionCooldown(), ~Spell(), and SpellEvent::~SpellEvent().

◆ m_spellSchoolMask

◆ m_spellState

uint32 Spell::m_spellState
protected

◆ m_spellValue

◆ m_targets

SpellCastTargets Spell::m_targets

Referenced by _cast(), CalculateDelayMomentForDst(), CheckCast(), CheckDst(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckRange(), CheckSrc(), Unit::DealDamage(), DoAllEffectOnTarget(), DoSpellHitOnUnit(), EffectBind(), EffectChargeDest(), EffectEnchantItemPerm(), EffectJumpDest(), EffectKnockBack(), EffectLeap(), EffectPullTowards(), EffectSkinPlayerCorpse(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerSpell(), SpellScript::GetExplTargetDest(), SpellScript::GetExplTargetGObj(), SpellScript::GetExplTargetItem(), SpellScript::GetExplTargetUnit(), SpellScript::GetExplTargetWorldObject(), handle_delayed(), WorldSession::HandleAcceptTradeOpcode(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), spell_vehicle_throw_passenger::HandleScript(), WorldSession::HandleUpdateMissileTrajectory(), WorldSession::HandleUpdateProjectilePosition(), InitExplicitTargets(), spell_ioc_launch::Launch(), OnSpellLaunch(), prepare(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitChannelTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTargetObjectTargets(), SelectImplicitTrajTargets(), SelectSpellTargets(), SendChannelStart(), SendSpellGo(), SendSpellStart(), SpellScript::SetExplTargetDest(), TakeCastItem(), TakePower(), TakeReagents(), update(), and UpdatePointers().

◆ m_timer

◆ m_triggeredByAuraSpell

◆ m_UniqueGOTargetInfo

◆ m_UniqueItemInfo

◆ m_UniqueTargetInfo

◆ m_weaponItem

Item* Spell::m_weaponItem

◆ unitTarget

Unit* Spell::unitTarget
protected

Referenced by CheckCast(), DoAllEffectOnTarget(), DoCreateItem(), DoSpellHitOnUnit(), EffectActivateSpec(), EffectAddComboPoints(), EffectAddExtraAttacks(), EffectAddHonor(), EffectApplyAreaAura(), EffectApplyAura(), EffectBind(), EffectCharge(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDiscoverTaxi(), EffectDismissPet(), EffectDispel(), EffectDispelMechanic(), EffectDistract(), EffectDualWield(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectForceCast(), EffectHeal(), EffectHealMaxHealth(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInebriate(), EffectInstaKill(), EffectInterruptCast(), EffectJump(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectModifyThreatPercent(), EffectPickPocket(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectRemoveAura(), EffectRenamePet(), EffectReputation(), EffectResurrect(), EffectResurrectNew(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSendEvent(), EffectSendTaxi(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectSpecCount(), EffectStealBeneficialBuff(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTriggerMissileSpell(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), SpellScript::GetHitCreature(), SpellScript::GetHitPlayer(), SpellScript::GetHitUnit(), HandleEffects(), SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitChainTargets(), SelectImplicitTrajTargets(), and Spell().


The documentation for this class was generated from the following files: